Re: [go-nuts] Is it possible to switch on type T in a generic function?

2022-11-09 Thread 'Mark' via golang-nuts
Thank you! I've now switched to using any as you suggested & also use 
strings.Builder.

On Wednesday, November 9, 2022 at 4:33:48 PM UTC dun...@harris3.org wrote:

> > 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)
>
> You need to convert to "any": https://go.dev/play/p/1pMhs22S-8P
>
> P.S. It would be better to use https://pkg.go.dev/strings#Builder for 
> building a string
>
> On Tuesday, 8 November 2022 at 13:09:51 UTC Mark wrote:
>
>> 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  package, which, 
>>> as luck would have it, has been factored out into an externally 
>>> available package 
>>> . 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
  
 
 .

>>>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving 

Re: [go-nuts] Is it possible to switch on type T in a generic function?

2022-11-09 Thread Duncan Harris
> 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)

You need to convert to "any": https://go.dev/play/p/1pMhs22S-8P

P.S. It would be better to use https://pkg.go.dev/strings#Builder for 
building a string

On Tuesday, 8 November 2022 at 13:09:51 UTC Mark wrote:

> 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  package, which, 
>> as luck would have it, has been factored out into an externally 
>> available package 
>> . 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
>>>  
>>> 
>>> .
>>>
>>

-- 
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/3169ebd2-d854-4e7d-addd-9b11918feb45n%40googlegroups.com.


Re: [go-nuts] Is it possible to switch on type T in a generic function?

2022-11-08 Thread 'Mark' via golang-nuts
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  package, which, as 
> luck would have it, has been factored out into an externally available 
> package . 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
>>  
>> 
>> .
>>
>

-- 
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.


Re: [go-nuts] Is it possible to switch on type T in a generic function?

2022-11-08 Thread roger peppe
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  package, which, as
luck would have it, has been factored out into an externally available
package . 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 <
golang-nuts@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+unsubscr...@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
> 
> .
>

-- 
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/CAJhgacibPQ%3DbgK74G4YSiyHdQQrNZJpahFph3Zz2%2BhDe_2j_0g%40mail.gmail.com.


Re: [go-nuts] Is it possible to switch on type T in a generic function?

2022-11-08 Thread Jan Mercl
On Tue, Nov 8, 2022 at 10:56 AM 'Mark' via golang-nuts
 wrote:
> // Want to sort by T < T //
> elements := make([]string, 0, len(me))
> for element := range me {
> elements = append(elements, fmt.Sprintf("%#v", element))
> }
> sort.Strings(elements)
> /


Not tested:

// Want to sort by T < T //
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]) })
/

But you need to extend the less function to handle mixed types. Like
in less(42, "foo").

-- 
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/CAA40n-UC7NevL7EtrLNb9rJRDSXDtf9AaZ-FX497b41XR2jJ5A%40mail.gmail.com.


Re: [go-nuts] Is it possible to switch on type T in a generic function?

2022-11-08 Thread 'Mark' via golang-nuts
I see that your example works, but I can't see how to adapt it to my use 
case.

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 {
// Want to sort by T < T //
elements := make([]string, 0, len(me))
for element := range me {
elements = append(elements, fmt.Sprintf("%#v", element))
}
sort.Strings(elements)
/
s := "{"
sep := ""
for _, element := range elements {
s += fmt.Sprintf("%s%s", sep, element)
sep = " "
}
return s + "}"
}

On Tuesday, November 8, 2022 at 9:19:48 AM UTC Jan Mercl wrote:

> On Tue, Nov 8, 2022 at 9:53 AM 'Mark' via golang-nuts
>  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.
>
> https://go.dev/play/p/zxQYVvOMX35 ?
>

-- 
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/577c056e-bf3f-4002-b431-f73aeda75a6dn%40googlegroups.com.


Re: [go-nuts] Is it possible to switch on type T in a generic function?

2022-11-08 Thread Jan Mercl
On Tue, Nov 8, 2022 at 9:53 AM 'Mark' via golang-nuts
 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.

https://go.dev/play/p/zxQYVvOMX35 ?

-- 
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/CAA40n-Xei-qGr149VjURsfKOp42THVTBowGeFxHY_bdwowYMmQ%40mail.gmail.com.


[go-nuts] Is it possible to switch on type T in a generic function?

2022-11-08 Thread 'Mark' via golang-nuts
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+unsubscr...@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.