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

sne*_*eeu 6 haskell type-constraints

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

ghci> :t (==)  
(==) :: (Eq a) => a -> a -> Bool
Run Code Online (Sandbox Code Playgroud)

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

ghci> :t (==)  
(==) :: Eq -> Eq -> Bool
Run Code Online (Sandbox Code Playgroud)

sep*_*p2k 9

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

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

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


Yit*_*itz 7

在Haskell中,"类型"只能有一组特定的可能值,这些值不与任何其他类型重叠.没有一种类型是"另一种"或另一种类型的"子类型".

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

但是类型变量可以引用任何 类型.我们并不总是知道如何为绝对的每种类型定义我们的函数.例如,该(>) 函数仅对其元素具有可比性的类型有意义.编译器将拒绝其类型签名过于笼统的函数,以帮助我们避免编写乱码.

在您的示例中,Eq不是类型.它是一个 类型类 - 一组类型的名称.我们使用class关键字声明类型类名称,并使用关键字将类型添加到类中instance .类型类的目的是在约束中使用以限制类型变量的范围.

类型和多态的Haskell方法基于"Hindley-Milner类型系统".它是一种非常精确但非常富有表现力的描述数据的方式,可以更轻松地为编译器提供有关程序中类型的大量信息.这种智能有助于编译器自动推断类型,为您提供正确的程序帮助,优化编译结果以及其他好处.

但要小心 - 它与OOP中使用的类型的方式非常不同,这可能是您习惯的方式.OO程序和Haskell程序之间通常没有直接的转换.你必须从一开始就以不同的方式思考这项任务.要特别注意不要将Haskell的"类"和"实例"概念与OOP中使用这些词的方式完全不同.