试图理解Haskell的=> vs定义类型

时间:2010-06-28 21:07:32

标签: haskell type-constraints

在Haskell中,为什么要定义具有类型约束的函数:

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

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

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

2 个答案:

答案 0 :(得分:8)

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

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

因此,如果要定义一个可以接受满足特定条件的不同类型值的函数,则需要输入类型。

答案 1 :(得分:7)

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

当我们想要多态时,即可以应用于多个的函数 一种类型,我们可以通过在类型中使用类型变量来指定 功能的签名。

但是类型变量可以引用任何 完全打字。我们并不总是知道如何定义我们的功能 绝对适合所有类型。例如,(>) 函数仅对其元素类型有意义 可比。编译器会拒绝 类型签名过于笼统的函数 帮助我们避免写胡言乱语。

在您的示例中,Eq不是类型。它是一个 类型类 - 一组类型的名称。我们宣布 使用class关键字的类型名称和 使用instance将类型添加到类中 关键词。类型类的目的是在a中使用 约束限制 类型变量的范围。

Haskell对类型和多态的方法是基于 “Hindley-Milner型系统”。这是非常精确的 但是非常富有表现力的描述数据的方式 更容易给编译器提供大量的智能 关于程序中的类型。这种情报有助于 编译器自动推断类型,给你 在帮助您的程序正确和优化方面提供了很多帮助 汇总结果以及其他好处。

但要小心 - 它与类型的方式非常不同 在OOP中使用,这可能是你习惯的。通常没有 OO程序和Haskell程序之间的直接转换。 你必须以不同的方式考虑这项任务 开始。要特别注意不要混淆Haskell的概念 “阶级”和“实例”与那些完全不同的方式 OOP中使用了单词。