英文:
Haskell's TypeClasses and Go's Interfaces
问题
Haskell的TypeClasses和Go的Interfaces之间有哪些相似之处和不同之处?这两种方法的相对优点/缺点是什么?
英文:
What are the similarities and the differences between Haskell's TypeClasses and Go's Interfaces? What are the relative merits / demerits of the two approaches?
答案1
得分: 25
看起来Go的接口与Haskell中的单参数类型类(构造器类)只在表面上有些相似。
- 方法与接口类型相关联
- 对象(特定类型)可以有该接口的实现
我不清楚Go是否以任何方式通过接口支持有界多态性,这是类型类的主要目的。也就是说,在Haskell中,接口方法可以在不同的类型上使用,
class I a where
put :: a -> IO ()
get :: IO a
instance I Int where
...
instance I Double where
....
所以我的问题是Go是否支持类型多态性。如果不支持,它们实际上并不像类型类。它们实际上并不可比较。
Haskell的类型类通过“泛型”(higher kinded polymorphism)实现了强大的代码重用,关于跨语言支持这种形式的通用程序的良好参考是这篇论文。
通过类型类实现的特定或有界多态性在这里有很好的描述。这是类型类在Haskell中的主要目的,而Go接口并没有解决这个问题,这意味着它们实际上并不相似。接口的功能严格来说更弱 - 一种零阶类型类。
英文:
Looks like only in superficial ways are Go interfaces like single parameter type classes (constructor classes) in Haskell.
- Methods are associated with an interface type
- Objects (particular types) may have implementations of that interface
It is unclear to me whether Go in any way supports bounded polymorphism via interfaces, which is the primary purpose of type classes. That is, in Haskell, the interface methods may be used at different types,
class I a where
put :: a -> IO ()
get :: IO a
instance I Int where
...
instance I Double where
....
So my question is whether Go supports type polymorphism. If not, they're not really like type classes at all. And they're not really comparable.
Haskell's type classes allow powerful reuse of code via "generics" -- higher kinded polymorphism -- a good reference for cross-language support for such forms of generic program is this paper.
Ad hoc, or bounded polymorphism, via type classes, is well described here. This is the primary purpose of type classes in Haskell, and one not addressed via Go interfaces, meaning they're not really very similar at all. Interfaces are strictly less powerful - a kind of zeroth-order type class.
答案2
得分: 9
我将在Don Stewart的出色回答的基础上补充一点,Haskell的类型类的一个令人惊讶的结果之一是,你可以在编译时使用逻辑编程来生成任意多个类的实例。(Haskell的类型类系统包括了一个与Datalog非常相似的无剪切子集)这个系统在QuickCheck库中被广泛利用。或者举一个非常简单的例子,你可以看看如何定义一个适用于任意元数谓词的布尔补(not
)的版本。我怀疑这种能力是类型类系统的一个意外结果,但它已经被证明非常强大。
Go语言没有类似的功能。
英文:
I will add to Don Stewart's excellent answer that one of the surprising consquences of Haskell's type classes is that you can use logic programming at compile time to generate arbitrarily many instances of a class. (Haskell's type-class system includes what is effectively a cut-free subset of Prolog, very similar to Datalog.) This system is exploited to great effect in the QuickCheck library. Or for a very simple example, you can see how to define a version of Boolean complement (not
) that works on predicates of arbitrary arity. I suspect this ability was an unintended consequence of the type-class system, but it has proven incredibly powerful.
Go has nothing like it.
答案3
得分: 7
- 在Haskell中,类型类的实例化是显式的(即你必须使用
instance Foo Bar
来使Bar成为Foo的实例),而在Go中,实现接口是隐式的(即当你定义一个定义了正确方法的类时,它会自动实现相应的接口,无需像implement InterfaceName
这样说)。 - 接口只能描述实例作为接收器的方法。在类型类中,实例化类型可以出现在任何参数位置或函数的返回类型中(即你可以说,如果Foo是Bar类型的实例,那么必须有一个名为baz的函数,它接受一个Int并返回一个Foo - 你不能用接口来表示这一点)。
英文:
- In haskell typeclass instantiation is explicit (i.e. you have to say
instance Foo Bar
for Bar to be an instance of Foo), while in go implementing an interface is implicit (i.e. when you define a class that defines the right methods, it automatically implements the according interface without having to say something likeimplement InterfaceName
). - An interface can only describe methods where the instance of the interface is the receiver. In a typeclass the instantiating type can appear at any argument position or the return type of a function (i.e. you can say, if Foo is an instance of type Bar there must be a function named baz, which takes an Int and returns a Foo - you can't say that with interfaces).
答案4
得分: 5
非常表面的相似之处,Go的接口更像是OCaml中的结构子类型化。
英文:
Very superficial similarities, Go's interfaces are more like structural sub-typing in OCaml.
答案5
得分: 3
C++ Concepts(没有被纳入C++0x标准)类似于Haskell的类型类。还有一些在Haskell中不存在的“公理”。它们允许您形式化像单子定律这样的事物。
英文:
C++ Concepts (that didn't make it into C++0x) are like Haskell type classes. There were also "axioms" which aren't present in Haskell at all. They let you formalize things like the monad laws.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论