Java 的接口和 Haskell 的类型类:异同? [英] Java's Interface and Haskell's type class: differences and similarities?

查看:32
本文介绍了Java 的接口和 Haskell 的类型类:异同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在学习 Haskell 时,我注意到它的类型类,这应该是源自 Haskell 的一项伟大发明.

While I am learning Haskell, I noticed its type class, which is supposed to be a great invention that originated from Haskell.

但是,在维基百科页面上的类型类:

程序员通过指定一组函数或必须存在的常量名称及其各自的类型对于属于该类的每个类型.

The programmer defines a type class by specifying a set of function or constant names, together with their respective types, that must exist for every type that belongs to the class.

对我来说这似乎与 Java 的接口相当接近(引用 维基百科的接口(Java)页):

Which seems rather close to Java's Interface to me (quoting Wikipedia's Interface(Java) page):

Java 编程语言中的接口是一种抽象类型用于指定接口(在术语的一般意义上)类必须实现.

An interface in the Java programming language is an abstract type that is used to specify an interface (in the generic sense of the term) that classes must implement.

这两个看起来很相似:类型类限制了类型的行为,而接口限制了类的行为.

These two looks rather similar: type class limit a type's behavior, while interface limit a class' behavior.

我想知道 Haskell 中的类型类和 Java 中的接口有什么区别和相似之处,或者它们根本不同?

I wonder what are the differences and similarities between type class in Haskell and interface in Java, or maybe they are fundamentally different?

我注意到甚至haskell.org也承认它们很相似.如果它们如此相似(或者它们是?),那么为什么类型类会被如此炒作?

I noticed even haskell.org admits that they are similar. If they are so similar (or are they?), then why type class is treated with such hype?

更多哇,这么多很棒的答案!我想我必须让社区来决定哪个是最好的.然而,在阅读答案时,他们似乎都只是在说类型类可以做很多事情,而接口不能或必须处理泛型".我不禁想知道,有没有什么接口可以做而类型类不能做的事情?另外,我注意到维基百科声称类型类最初是在 1989 年的论文中发明的 *如何使临时多态性更少广告hoc",而 Haskell 仍处于摇篮中,而 Java 项目始于 1991 年,并于 1995 年首次发布.那么 也许不是类型类类似于接口,相反,接口受类型类的影响? 是否有任何文件/论文支持或反驳这一点?谢谢大家的回答,很有启发!

MORE Wow, so many great answers! I guess I'll have to let the community decide which is the best one. However, while reading the answers, all of them seem to just say that "there are many things typeclass can do while interface cannot or have to cope with generics". I cannot help but wondering, are there anything interfaces can do while typeclasses cannot? Also, I noticed that Wikipedia claims that typeclass was originally invented in the 1989 paper *"How to make ad-hoc polymorphism less ad hoc", while Haskell is still in its cradle, while Java project was started in 1991 and first released in 1995. So maybe instead of typeclass being similar to interfaces, its the other way around, that interfaces were influenced by typeclass? Are there any documents/papers support or disprove this? Thanks for all the answers, they are all very enlightening!

感谢所有的投入!

推荐答案

我会说接口有点像类型类 SomeInterface t,其中所有的值都具有 类型t->任何(其中whatever 不包含t).这是因为在 Java 和类似语言中的那种继承关系,调用的方法取决于它们被调用的对象的类型,而不是别的.

I would say that an interface is kind of like a type class SomeInterface t where all of the values have the type t -> whatever (where whatever does not contain t). This is because with the kind of inheritance relationship in Java and similar languages, the method called depends on the type of object they are called on, and nothing else.

这意味着制作像 add :: t -> 这样的东西真的很困难.t->t 带有接口,它在多个参数上是多态的,因为接口无法指定方法的参数类型和返回类型与它所在的对象类型相同调用(即自我"类型).使用泛型,有一些方法可以通过创建一个带有泛型参数的接口来伪造这一点,该接口预计与对象本身的类型相同,例如 Comparable 如何做到这一点,在你期望的地方使用 Foo 实现 Comparable 以便 compareTo(T otherobject) 类型具有 t ->t->订购.但这仍然需要程序员遵循这个规则,而且当人们想要制作一个使用这个接口的函数时也很头疼,他们必须有递归的泛型类型参数.

That means it's really hard to make things like add :: t -> t -> t with an interface, where it is polymorphic on more than one parameter, because there's no way for the interface to specify that the argument type and return type of the method is the same type as the type of the object it is called on (i.e. the "self" type). With Generics, there are kinda ways to fake this by making an interface with generic parameter that is expected to be the same type as the object itself, like how Comparable<T> does it, where you are expected to use Foo implements Comparable<Foo> so that the compareTo(T otherobject) kind of has type t -> t -> Ordering. But that still requires the programmer to follow this rule, and also causes headaches when people want to make a function that uses this interface, they have to have recursive generic type parameters.

另外,你不会有 empty :: t 之类的东西,因为你不是在这里调用函数,所以它不是方法.

Also, you won't have things like empty :: t because you're not calling a function here, so it isn't a method.

这篇关于Java 的接口和 Haskell 的类型类:异同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆