On Sun, Apr 10, 2022, 11:42 AM Aidan Hahn <aidanjacobh...@gmail.com> wrote:

> Hello Ian,
>
> I think some of your confusion may be because the function is poorly
> named. In some cases the Node generic may store another Node in the generic
> Inner field.
> In this case I want my preorder traversal to also traverse the list in the
> Inner field. "TreePreTraverse" would be a better name.
>
> func (n *Node[any]) TreePreTraverse(f func(*Node[any])) {
>


Maybe I didn't emphasize this, but don't write Node[any].  That doesn't
make sense.  That is saying that the type parameter is named "any".  Write
Node[T] or something similar.

Ian



    tmpN := interface{}(n)
>     if tmpN, ok := tmpN.(*Node[*Node[any]]); ok {
>         tmpN.Inner.TreePreTraverse(f)
>     } else {
>         f(n)
>     }
>
>     if n.Next != nil {
>         n.Next.TreePreTraverse(f)
>     }
> }
>
> Additionally, I notice that you set the "Next" field to *Node[T] mirroring
> the type of the parent Node, but part of my goal with this exercise is to
> be able to have a list of elements of varying type. If I set the generic
> type for the Next field to 'T' then the list has to be homogeneous.
>
> Ignoring the weird corner case, I am just wondering why f, unchanged,
> cannot be passed into a recursion of the function that it is an argument to.
>
> Thanks,
> Ava
> On Saturday, April 9, 2022 at 9:13:31 PM UTC-7 Ian Lance Taylor wrote:
>
>> On Sat, Apr 9, 2022 at 8:28 PM Aidan Hahn <aidanja...@gmail.com> wrote:
>> >
>> > I am playing with the generics that were added in go 1.18 and noticed
>> an odd discrepancy that I have not been able to find an authoritative
>> answer to. Consider the following data type, as well as the function
>> defined for it:
>> >
>> > type Node[T any] struct {
>> > Inner T
>> > Next *Node[any]
>> > }
>> >
>> > func (n *Node[any]) ListPreTraverse(f func(*Node[any])) {
>> > tmpN := interface{}(n)
>> > if tmpN, ok := tmpN.(*Node[*Node[any]]); ok {
>> > tmpN.Inner.ListPreTraverse(f)
>> > } else {
>> > f(n)
>> > }
>> > n.Next.ListPreTraverse(f)
>> > }
>> >
>> > This function is a simple attempt to iterate across a generic linked
>> list and call a function on each node in the list (although in this case it
>> may behave more like a tree if inner stores another node). When I went to
>> compile this code I encountered the following error:
>> >
>> > test.go:64:25: cannot use f (variable of type func(*Node[any])) as type
>> func(*Node[any]) in argument to n.Next.ListPreTraverse
>> >
>> > To me at least it seems that all the information to validate that the
>> argument fits the type specified in the function call is there, defined in
>> the function header. What am I missing?
>>
>> The error message is confusing because the "any" used in
>> ListPreTraverse is shadowing the "any" used in Node. See
>> https://go.dev/doc/faq#types_in_method_declaration. You want to write
>>
>> func (n *Node[T]) ListPreTraverse(f func(*Node[T])) {
>>
>> But then you will see that your code has an instantiation cycle,
>> violating the restriction described at
>>
>> https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#generic-types:
>>
>> "A generic type can refer to itself in cases where a type can
>> ordinarily refer to itself, but when it does so the type arguments
>> must be the type parameters, listed in the same order. This
>> restriction prevents infinite recursion of type instantiation."
>>
>> I don't really understand what you are trying to do here. The type
>> assertion doesn't make sense to me. Perhaps this is the code you
>> want:
>>
>> type Node[T any] struct {
>> Inner T
>> Next *Node[T]
>> }
>>
>> func (n *Node[T]) ListPreTraverse(f func(*Node[T])) {
>> f(n)
>> if n.Next != nil {
>> n.Next.ListPreTraverse(f)
>> }
>> }
>>
>> Ian
>>
> --
> 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/019beabf-a1f5-4aeb-96d4-c121ae3c2252n%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/019beabf-a1f5-4aeb-96d4-c121ae3c2252n%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/CAOyqgcX2gGAsJ_W%3D36RU%2BfwZO54DFY6tNGrj8RB-fV75%3D_T-sg%40mail.gmail.com.

Reply via email to