我可以看到Haskell中的“class”更简洁,而且效率也更高。但是,我有一种感觉,理论上,“阶级”和“抽象阶级”是相同的。
你有什么看法?
答案 0 :(得分:7)
呃,不是,不是。
首先,Haskell的类型类没有构造函数;数据类型。
此外,类型类实例并未真正附加到它定义的类型,它更像是一个单独的实体。您可以单独导入实例和数据定义,并且通常考虑“这个数据属于哪个类”是没有意义的。类型类中的函数也不能对定义实例的数据类型进行任何特殊访问。
类型类实际定义的是一组标识符,这些标识符可以在显式的每种类型的基础上共享以在概念上等效的事物(在某种意义上)与不同的数据类型。这就是它被称为 ad-hoc多态的原因,与您从常规类型变量中获得的标准参数多态形成对比。
它更接近某些语言中的“重载函数”,其中不同的函数被赋予相同的名称,并且调度基于参数类型完成(出于某种原因,其他语言通常不允许基于返回的重载类型,虽然这对类型类没有任何问题。)
答案 1 :(得分:4)
除了实现差异之外,一个主要的概念差异是关于何时声明类/类型。
如果您创建一个新类MyClass,例如在Java或C#中,您需要指定它在开发类时提供的所有接口。现在,如果将代码捆绑到库中并将其提供给第三方,则它们会受到您决定使用的接口的限制。如果他们想要额外的接口,他们必须创建派生类,TheyDerivedClass。不幸的是,你的库可能在不知道派生类的情况下制作副本或MyClass,并且可能通过它们必须包装的接口返回新实例。因此,要真正为类添加新接口,他们必须在库的顶部添加一个全新的层。不优雅,也不实用。
对于类型类,您可以指定类型与类型定义分开提供的接口。如果第三方库现在包含YourType,我可以在我自己的代码中将YourType实例化为属于新接口(在创建类型时未提供)。
因此,类型类允许类型的用户控制类型所遵循的接口,而使用“普通”类,开发者 class处于控制之中(并且必须有水晶球才能看到用户可能想要使用该类的所有可能的东西)。
答案 2 :(得分:2)
来自:http://www.haskell.org/tutorial/classes.html
在继续使用类型类的更多示例之前,值得指出Haskell类型类的另外两个视图。第一个是类比面向对象编程(OOP)。在下面关于OOP的一般声明中,只需将type类替换为class,并输入object作为对象,就可以得到Haskell类型类机制的有效摘要:
“类捕获常见的操作集。特定对象可以是类的实例,并且将具有与每个操作相对应的方法。类可以按层次排列,形成超类和子类的概念,并允许继承操作/方法。默认方法也可以与操作相关联。“
与OOP相反,应该清楚类型不是对象,特别是没有对象或类型的内部可变状态的概念。与某些OOP语言相比,Haskell中的方法完全是类型安全的:任何将方法应用于类型不在所需类中的值的尝试都将在编译时而不是在运行时检测到。换句话说,方法不是在运行时“查找”,而是简单地作为高阶函数传递。
答案 3 :(得分:0)
此幻灯片可以帮助您了解OO抽象类和Haskell类型类之间的相似点和不同点:Classes, Jim, But Not As We Know Them。