Haskell的TypeClasses和Go的接口

Jer*_*ose 29 haskell programming-languages interface go typeclass

Haskell的TypeClasses和Go的接口有什么相似之处和不同之处?这两种方法的相对优点/缺点是什么?

Don*_*art 24

看起来只有表面的方式是Go接口,如Haskell中的单参数类型类(构造函数类).

  • 方法与接口类型相关联
  • 对象(特定类型)可以具有该接口的实现

我不清楚Go是否以任何方式通过接口支持有界多态性,这是类型类的主要目的.也就是说,在Haskell中,接口方法可以用于不同类型,

class I a where
    put :: a -> IO ()
    get :: IO a

instance I Int where
    ...

instance I Double where
    ....
Run Code Online (Sandbox Code Playgroud)

所以我的问题是Go是否支持类型多态.如果没有,他们根本不喜欢类型类.他们并没有真正的可比性.

Haskell的类型类允许通过"泛型"强大地重用代码 - 更高的kinded多态性 - 这种通用程序形式的跨语言支持的良好参考是本文.

通过类型类的Ad hoc或有界多态,在这里很好的描述.这是Haskell中类型类的主要目的,并且没有通过Go接口解决,这意味着它们根本不是非常相似.接口严格不那么强大 - 一种零阶类型.

  • 实际上,两者之间的唯一关系似乎是在两种情况下,"方法"都独立于"阶级".就是这样. (4认同)
  • Go的接口支持"有界多态性",正如维基百科文章所严格定义的那样,只需在函数的签名中命名所需的接口即可.例如,如果我写"func foo(a,b IBar)",那么编译器确保我只能传入支持IBar的结构.但是,Haskell的类型类支持非结构类型,甚至复合绑定(例如,func foo(a,b(IBar && IBaz))在Go中是非法的,但是(IBar a,IBaz a)=> foo :: a - > b - > ......完全合法).你必须在Go中创建一个复合界面来做类似的事情(vis.io.ReadCloser). (2认同)

sep*_*p2k 7

  1. 在haskell中,类型类实例化是显式的(即你必须说instance Foo BarBar是Foo的一个实例),而在实现中,接口是隐式的(即当你定义一个定义正确方法的类时,它会自动实现相应的接口而不用不得不说些什么implement InterfaceName.
  2. 接口只能描述接口实例是接收者的方法.在类型类中,实例化类型可以出现在任何参数位置或函数的返回类型中(也就是说,如果Foo是类型为Bar的实例,则必须有一个名为baz的函数,它接受一个I​​nt并返回一个Foo - 你不能说用接口).

  • 缺少多态性严重限制了Go接口与类型类相关的程度.我会说,在实例方法中没有多态性,除了表面上之外,它们并没有真正相关. (4认同)

Nor*_*sey 6

我将补充Don Stewart的优秀答案,即Haskell类型类的一个令人惊讶的后果是,您可以在编译时使用逻辑编程来生成任意多个类的实例.(Haskell的类型系统包括Prolog的无切割子集,与Datalog非常相似.)该系统在QuickCheck库中被充分利用.或者,对于一个非常简单的示例,您可以看到如何定义适用于任意arity谓词的Boolean补充(not)版本.我怀疑这种能力是类型级系统的意外后果,但事实证明它非常强大.

Go没有什么比这更好的了.


snk*_*kid 5

非常肤浅的相似之处,Go的界面更像是OCaml中的结构子类型.