2010-06-28 60 views
6

在Haskell,你为什么会定义一个类型约束功能:试图了解Haskell的=> VS定义类型

ghci> :t (==) 
(==) :: (Eq a) => a -> a -> Bool 

而不是定义它,所以它的类型是:

ghci> :t (==) 
(==) :: Eq -> Eq -> Bool 
+0

hese两个语句不相等 – 2010-06-28 21:11:33

回答

8

你不会做第二个版本,因为你会得到一个编译错误。 Eq不是一个类型,它是一个类型类型。你不能在需要类型的地方使用类型类。

如果你没有定义自己的类型MyEq,然后定义一个函数==与类型MyEq -> MyEq -> Bool,表达"hello" == "hello"会因为"hello"是一个String类型的值,而不是类型MyEq的是无效的。由于haskell中没有子类型,因此值不能同时为String类型和MyEq类型。

所以,如果你想定义,它可以接受不同类型的符合一定条件的值的功能,你需要类型类。

+0

要跟上这一点,请参阅运行'let a :: Eq - > Eq - > Bool得到的错误; a b c = b == c;在ghci的2 2'中。 – 2010-06-28 21:13:39

+0

谢谢你们,这会让事情变得直白! – sneeu 2010-06-28 21:26:18

7

在Haskell中,“类型”只能有一组特定的可能值 ,它们不会与任何其他类型重叠。 没有一种类型是“另一种” 或“另一种类型的子类型”。

当我们需要多态性时,即可以应用于多于一个类型的函数时,我们可以指定通过使用函数的 类型的类型变量。

但是一个类型变量可以参考任何 类型。我们并不总是知道如何为绝对每种类型定义我们的功能 。例如,(>) 函数仅适用于元素类型为 的类型。编译器将拒绝 函数,其类型签名过于笼统,为了帮助我们避免编写乱码,请按 排序。

在你的榜样,Eq不是一个类型。它是一个 类型类 - 一组类型的名称。我们声明使用class关键字 类型类的名称,并添加 类型转换成使用instance 关键字的类。类型类型的目的是用于约束 限制类型变量的作用域。

Haskell的方法类型和多态性是基于 “辛德米尔纳型系统”上。它是描述数据,使得它更容易 给编译器一个巨大的智力 的金额约在你的程序的类型极其精确 又极富表现力的方式。智力帮助 编译器自动推断类型,给你 一个很大的帮助让你的程序是正确的,并优化 编译的结果,还有其他好处。

但要小心 - 它与OOP中使用的类型是 的方式非常不同,这可能是您习惯的方式。OO程序和Haskell程序之间通常不存在直接翻译。 你必须以不同的方式从 开始考虑任务。特别注意不要将“class”和“instance”的Haskell概念 与在OOP中使用这些 单词的方式完全不同。

+0

“它与OOP中使用的类型非常不同”,我不同意。 Haskell类型类真的很像OOP中的“抽象类”或“接口”,我怀疑有些vtable会随着参数传递给运行时调度发生的多态函数。 – 2010-06-30 08:38:40