Thanks for your help and very interesting ideas. In the end I used this:

type Set[T comparable] map[T]struct{}

func New[T comparable](elements ...T) Set[T] {
    set := make(Set[T], len(elements))
    for _, element := range elements {
        set[element] = struct{}{}
    }
    return set
}

func (me Set[T]) String() string {
    elements := make([]T, 0, len(me))
    for element := range me {
        elements = append(elements, element)
    }
    sort.Slice(elements, func(i, j int) bool {
        return less(elements[i], elements[j])
    })
    s := "{"
    sep := ""
    for _, element := range elements {
        s += sep + asStr(element)
        sep = " "
    }
    return s + "}"
}

func asStr(x any) string {
    if s, ok := x.(string); ok {
        return fmt.Sprintf("%q", s)
    }
    return fmt.Sprintf("%v", x)
}

func less(a, b any) bool {
    switch x := a.(type) {
    case int:
        return x < b.(int)
    case float64:
        return x < b.(float64)
    case string:
        return x < b.(string)
    default:
        return fmt.Sprintf("%v", a) < fmt.Sprintf("%v", b)
    }
}

Interestingly, I couldn't put the asStr() code in the String() function 
since doing so produced this error:

invalid operation: cannot use type assertion on type parameter value 
element (variable of type T constrained by comparable)

Anyway, I'm happy that it all works now. (I know I ought to include every 
int & float32, but this is enough for now).



On Tuesday, November 8, 2022 at 11:29:34 AM UTC rog wrote:

> If you're sure that T is an int or a string, then why not constrain it as 
> such? https://go.dev/play/p/1kT6EacMHco
>
> You could go further and constrain it to allow any type with ordering 
> defined: https://go.dev/play/p/il5koj1RPkh
>
> If you want to allow any kind of comparable key in your set, one could 
> observe that essentially you're trying to solve the same problem that the 
> fmt package is solving when it converts maps to string. It uses the 
> internal fmtsort <https://pkg.go.dev/internal/fmtsort> package, which, as 
> luck would have it, has been factored out into an externally available 
> package <https://pkg.go.dev/github.com/rogpeppe/go-internal/fmtsort>. So 
> you could do this: https://go.dev/play/p/oKTGSm_o22a
>
> To answer the specific question you asked, there is an issue that tracks 
> the ability to do a switch directly on a type parameter: 
> https://github.com/golang/go/issues/45380
>
> But you can also work around the lack of that feature by doing something 
> like this: https://go.dev/play/p/3C2a61Ojbxs
>
> Hope this helps,
>
>   rog.
>
>
> On Tue, 8 Nov 2022 at 08:53, 'Mark' via golang-nuts <
> golan...@googlegroups.com> wrote:
>
>> Given a function:
>>
>> func F[T comparable](a T) {
>> }
>>
>> is it possible to check T's type inside F?
>>
>> My use case is that I have a function with signature G[T comparable](x 
>> []T) and inside G I want to sort the elements in slice x where T could be 
>> int or string.
>>
>> This arises in a tiny generic set module I've created: 
>> https://github.com/mark-summerfield/gset
>> In the String() method I want to return a string with the elements sorted 
>> (for human readability and for testing convenience); but at the moment I 
>> can only do this by converting all elements to strings and sorting them 
>> which isn't good for ints.
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/e746f065-24fa-474a-90ec-2d8367bf3e3bn%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/e746f065-24fa-474a-90ec-2d8367bf3e3bn%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/dea0057c-fd75-4a05-a171-0a77bbd1d051n%40googlegroups.com.

Reply via email to