2 回答
TA贡献1876条经验 获得超5个赞
Go 的泛型和方法的组合不像 Haskell 的类型类那样富有表现力;至少还没有。特别是,正如 kostix 在他的评论中指出的那样,
Go 允许泛型类型具有方法,但是除了接收者之外,这些方法的参数不能使用参数化类型。
(来源)
由于 Go 方法不能引入新的类型参数,因此B
在您的方法中访问的唯一方法是像您所做的那样在您的类型fmap
声明中引入它。Functor
但这没有意义,因为根据类别理论,函子采用一个类型参数,而不是两个。
这个例子可能足以让您相信,在 Go 中使用泛型和方法来模拟 Haskell 类型类是徒劳的。
不过,您可以做的一件事是 implement fmap
,不是作为方法,而是作为顶级函数:
package main
import "fmt"
type S[A any] struct {
contents A
}
func Fmap[A, B any](sa S[A], f func(A) B) S[B] {
return S[B]{contents: f(sa.contents)}
}
func main() {
ss := S[string]{"foo"}
f := func(s string) int { return len(s) }
fmt.Println(Fmap(ss, f)) // {3}
}
但仅仅因为你可以并不意味着你应该。总是问问自己,将一种方法从其他语言转移到 Go 是否感觉正确。
TA贡献1803条经验 获得超3个赞
我要补充一点,您遇到的一些问题是您从错误的定义开始。提议中应该有一些直接的危险信号Functor——
type Functor [A any, B any] interface{
// ^ Functor should wrap a single type ⚠️
fmap(f func(A)B) B
// ^ should return Functor-wrapped B ⚠️
}
解决你上面的问题,这就是我们想写的 -
type Functor[A any] interface{
fmap[B any](f func(A)B) Functor[B]
}
然而,Go 警告我们就您面临的问题向我们提供直接反馈 -
interface method must have no type parameters
undefined: B
正如 @jub0bs 在链接的答案中指出的那样,方法可能不会采用额外的类型参数。
- 2 回答
- 0 关注
- 82 浏览
添加回答
举报