For a function, it makes sense to just write two functions, the easiest to use, and the one with maximum flaxibility.
func SortOrdered[T constraints.Ordered](s []T) {
// …
}
func Sort[T any](s []T, less func(T, T) bool) {
// …
}
For a data structure, I recommend using type SearchTree[T any] struct {
Less func(T, T) bool
// …
}
and then writing two constructors func NewSearchTree(less func(T, T) bool) *SearchTree[T] {
// …
return &SearchTree[T]{
Less: less,
// …
}
}
func NewOrderedSearchTree[T constraints.Ordered]() *SearchTree[T] {
// …
return &SearchTree[T]{
Less: func(x, y T) bool {return x < y},
// …
}
}