在Haskell中解释类型类 [英] Explain Type Classes in Haskell

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

问题描述

我是一个C ++ / Java程序员,我碰巧在日常编程中使用的主要范例是OOP。在某些线程我读了一个注释,类型类比OOP更直观。有人可以用简单的单词来解释类型类的概念,以便像我这样的OOP人可以理解它吗?

I am a C++ / Java programmer and the main paradigm I happen to use in everyday programming is OOP. In some thread I read a comment that Type classes are more intuitive in nature than OOP. Can someone explain the concept of type classes in simple words so that an OOP guy like me can understand it?

推荐答案

我总是很怀疑这个或那个程序结构更直观的说法。编程是反直觉的,总是会因为人们自然地根据具体情况而不是一般规则来思考。改变这需要训练和实践,或者称为学习编程。

First, I am always very suspicious of claims that this or that program structure is more intuitive. Programming is counter-intuitive and always will be because people naturally think in terms of specific cases rather than general rules. Changing this requires training and practice, otherwise known as "learning to program".

继续讨论问题的核心,OO类和Haskell类型类之间的主要区别是在OO中,类(即使是接口类)既是新类型(后代)的类型和模板。在Haskell中,类型类只是新类型的模板。更确切地说,类型类描述了共享公共接口的一组类型,但它本身不是类型

Moving on to the meat of the question, the key difference between OO classes and Haskell typeclasses is that in OO a class (even an interface class) is both a type and a template for new types (descendants). In Haskell a typeclass is only a template for new types. More precisely, a typeclass describes a set of types that share a common interface, but it is not itself a type.

Num描述具有加法,减法和乘法运算符的数字类型。 Integer类型是Num的一个实例,意味着Integer是实现这些运算符的类型集的成员。

So the typeclass "Num" describes numeric types with addition, subtraction and multiplication operators. The "Integer" type is an instance of "Num", meaning that Integer is a member of the set of types that implement those operators.

所以我可以写一个sum具有此类型的函数:

So I can write a summation function with this type:

sum :: Num a => [a] -> a

位于=>操作符左侧的位表示sum对于任何类型a是Num的实例。右边的位说明它接受类型a的值的列表,并返回类型a的单个值作为结果。所以你可以使用它来求和整数列表或双列表或复杂列表,因为它们都是Num的实例。当然,sum的实现将使用+运算符,这就是为什么你需要Num类型约束。

The bit to to the left of the "=>" operator says that "sum" will work for any type "a" that is an instance of Num. The bit to the right says it takes a list of values of type "a" and returns a single value of type "a" as a result. So you could use it to sum a list of Integers or a list of Doubles or a list of Complex, because they are all instances of "Num". The implementation of "sum" will use the "+" operator of course, which is why you need the "Num" type constraint.

但是你不能写: / p>

However you cannot write this:

sum :: [Num] -> Num

因为Num不是类型。

类型和类型类之间的区别是为什么我们不谈论Haskell中类型的继承和后代。 是类型类的继承:你可以将一个类型类声明为另一个类型的后代。这里的后代描述了由父描述的类型的子集。

This distinction between type and typeclass is why we don't talk about inheritance and descendants of types in Haskell. There is a sort of inheritance for typeclasses: you can declare one typeclass as a descendant of another. The descendant here describes a subset of the types described by parent.

这一切的一个重要结果是你不能在Haskell中有异类列表。在sum示例中,您可以传递一个整数列表或一个双精度列表,但不能在同一列表中混合双精度和整数。这看起来像一个棘手的限制;你将如何实现旧的汽车和货车是两种类型的车辆的例子?有几个答案取决于你实际尝试解决的问题,但一般原则是明确使用第一类函数而不是隐式使用虚拟函数来执行你的间接。

An important consequence of all this is that you can't have heterogenous lists in Haskell. In the "sum" example you can pass it a list of integers or a list of doubles, but you cannot mix doubles and integers in the same list. This looks like a tricky restriction; how would you implement the old "cars and lorries are both types of vehicle" example? There are several answers depending on the problem you are actually trying to solve, but the general principle is that you do your indirection explicitly using first-class functions rather than implicitly using virtual functions.

这篇关于在Haskell中解释类型类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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