在 Haskell 中,"=>符号"代表什么意思?

46

我对Haskell和函数式编程都比较新,对它的语法感到有些不舒服。

在以下代码中,=>是什么意思?还有(Num a,Ord a)

loop :: (Num a, Ord a) => a -> (t -> t) -> t -> t
4个回答

57
这是一个类型类约束; (Num a,Ord a) => ... 表示 loop 可以适用于任何类型 a,只要该类型是 NumOrd 类型类的实例,分别对应数字类型和排序类型。基本上,您可以将 loop 视为 => 右侧的类型,除了需要 aNumOrd 的实例之外。

您可以将类型类视为与 OOP 接口基本相似(但它们不是同一件事!)-它们封装了一组定义,任何实例都必须支持,并且可以使用这些定义编写通用代码。例如,Num 包括数字运算,如加法和乘法,而 Ord 包括小于、大于等运算。

有关类型类的更多信息,请参见 《Learn You a Haskell》 中的 此介绍


22

=>符号分隔类型签名的两个部分:

  • 左边是类型类约束
  • 右边是实际类型

因此,你可以将(Num a, Ord a) => a -> (t -> t) -> t -> t理解为“该类型是a -> (t -> t) -> t -> t,同时a必须有一个Num实例并且a还必须有一个Ord实例”。

有关类型类的更多信息,请参见http://www.learnyouahaskell.com/types-and-typeclasses


5

一种思考方式是,Ord aNum a 是函数的附加输入。不过它们是一种特殊的输入:字典。当你使用该函数与特定类型 a 时,必须为类型 a 上的 OrdNum 操作也提供字典。

任何使用具有字典输入函数的函数都必须具有相同的字典输入。

foo :: (Num a, Ord a) => a -> t
foo x = loop x someFunc someT

然而,您不必明确传递这些字典。 哈斯凯尔将为您处理,只要有可用的字典。 您可以使用类型类实例创建字典。

instance Num MyType with
  x + y = ...
  x - y = ...
  ...

这将为MyType上的Num操作创建一个字典,因此MyType可以在任何需要输入Num a的地方使用(当然,前提是它满足其他要求)。


2
值得澄清的是,尽管我们称它们为“字典”,但它们并不是哈希表,而是函数记录。它们有点像面向对象语言中的虚函数表,只是它们没有附加到值上。 - hammar

3
=>的左边,您声明用于右侧使用的类型的限制条件。
在您给出的示例中,它意味着a被限制为同时是Ord类型类和Num类型类的实例。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接