Go:自己的 List 类型与自己的 Functor 类型不兼容

为了更多地了解Go、泛型和函数式编程,我实现了一个List类型(摘自list.go):


package funcprog


type Function[T any] func(T) T


type List[T any] []T


func (l List[T]) Map(f Function[T]) List[T] {

    var ys List[T]

    for _, x := range l {

        y := f(x)

        ys = append(ys, y)

    }

    return ys

}

效果很好(main.go):


package main


import (

    "fmt"


    "funcprog"

)


func main() {

    numbers := funcprog.List[int]{0, 1, 2, 3}

    twice := func(x int) int { return x * 2 }

    fmt.Println(numbers.Map(twice))

}

$ go run main.go

[0 2 4 6]

我List的其实是一个Functor,所以我写了这个接口(functor.go):


package funcprog


type Functor[T any] interface {

    Map(Function[T]) Functor[T]

}

但是,如果我想将我List的用作Functor( main.go,已修改):


import (

    "fmt"


    "funcprog"

)


func demo[T int](f funcprog.Functor[T]) {

    fmt.Println(f.Map(func(x T) T { return x * 2 }))

}


func main() {

    numbers := funcprog.List[int]{0, 1, 2, 3}

    demo[int](numbers)

}

我收到此错误:


funcprog.List[int] does not implement funcprog.Functor[int] (wrong type for Map method)

    have Map(f funcprog.Function[int]) funcprog.List[int]

    want Map(funcprog.Function[int]) funcprog.Functor[int]

我的不List[int]也是一个Functor[int],因为List[T]满足Functor[T]吗?


慕妹3146593
浏览 106回答 2
2回答

UYOU

当查看一个类型是否实现了一个接口时,go 不会尝试对该函数签名的元素进行“接口映射”,它只会比较确切的签名。如果你想让你的List[T]类型实现你的Functor[T]接口,你应该改变Map()方法的签名:func (l List[T]) Map(f Function[T]) Functor[T] {    ...}额外提一点:这与泛型无关,而是与如何在接口上实现类型检查有关。这是另一个例子(没有泛型):type MyStr string// MyStr implements fmt.Stringerfunc (s MyStr) String() string {    return string(s)}// but this method does not fulfill the Concatter interface belowfunc (s MyStr) Concat(x string) MyStr {    return s + " " + MyStr(x)}type Concatter interface {    Concat(s string) fmt.Stringer}var _ Concatter = MyStr("") // compilation errorhttps://go.dev/play/p/tKDGEXlYHyl

慕丝7291255

函数签名中的类型必须完全匹配。所以你只需要改变List.Map方法的返回类型来返回一个Functor[T].func (l List[T]) Map(f Function[T]) Functor[T]现在可以编译了,因为List[T]确实用它自己的方法实现了 ,并且实例化 和共享相同的具体类型。Functor[T]MapdemoList固定游乐场:https ://go.dev/play/p/a4GeqXstjct我的List[int]不也是Functor[int]吗,因为List[T]满足Functor[T]?是的,但是 Go generics不支持任何形式的 type variance,因此List[T]在您的示例中返回方法签名不同于接口的方法签名。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go