->和=>符号之间的区别。他们的意思是什么?

时间:2019-06-25 20:24:03

标签: haskell

在Haskell中,当我们谈论类型声明时。

我见过->=>

作为一个例子:我可以进行自己的类型声明。

addMe :: Int -> Int -> Int
addMe x y = x + y

它很好用。

但是,如果我们看看:t sqrt,我们会得到:

sqrt :: Floating a => a -> a

什么时候使用=>,什么时候使用->? 什么时候使用“胖箭头”,什么时候使用“瘦箭头”?

3 个答案:

答案 0 :(得分:10)

->用于显式功能。即如果f可以用f x形式的表达式编写,则签名中必须带有以下箭头之一。具体来说,x的类型(自变量)必须出现在->箭头的左侧。

最好至少从一开始就不要将=>当作功能箭头。。从逻辑上讲,它是一个蕴涵箭头如果 a是具有属性 Floating a的类型,则它因此sqrt的签名是a -> a

对于您的addMe示例(该函数具有两个参数),签名必须始终为x -> y -> z形式。 可能在其前面可能还有一个q =>;不会影响功能性,但在允许使用哪种特定类型方面可能有一些说法。通常,如果类型已经固定且具体,则不需要此类约束。就像,您原则上可以对Int施加约束:

addMe :: Num Int => Int -> Int -> Int
addMe x y = x + y

...但这并不能真正起到任何作用,因为每个人都知道特定类型IntNum类的实例。需要 这样的约束的地方是类型不是固定的而是类型变量(即小写),即函数是否是多态的。你不能只是写

addMe' :: a -> a -> a
addMe' x y = x + y

因为该签名将暗示该函数适用于任何类型a,但它不适用于所有类型(例如,如何添加两个字符串?也许不是最好的例子,但是您怎么两个字符串?)

因此您需要约束

addMe' :: Num a => a -> a -> a
addMe' x y = x + y

这意味着,您不必在乎{em>确切类型a是什么,但是您确实要求它是数字类型。任何人都可以使用自己的类型MyNumType使用该函数,但他们需要确保满足Num MyNumType:然后{em>遵循 addMe'可以具有签名{{ 1}}。

确保这一点的方法是使用已知为数字的标准类型,例如MyNumType -> MyNumType -> MyNumType,或者为您的自定义类型和实例声明 Num class。只有在您确定这是个好主意的情况下,才做后者;通常,您只需要标准的num类型。


请注意,箭头在签名中可能不是可见:可以为函数类型使用类型同义词,例如{{ 1}},那么addMe' 5.9 3.7 :: Double没问题。但是您可以认为typedef本质上只是一个语法包装器。它仍然是相同的类型,并且确实有箭头。

碰巧逻辑暗示和函数应用可以看作是同一数学概念的两个方面。此外,GHC实际上将类约束实现为函数参数,即所谓的“字典”。但是所有这些都是在幕后发生的,因此,如果它们是隐式函数,那么它们就可以了。在标准的Haskell中,您将永远不会看到type IntEndofunc = Int -> Int类型的LHS作为该函数所应用于的某些实际参数的类型。

答案 1 :(得分:9)

“细箭头”用于函数类型(t1 -> t2是具有类型t1的值并产生类型t2的函数的类型)。 / p>

“胖箭头”用于类型约束。它将多态函数上的类型约束列表与其余类型分开。因此,给定Floating a => a -> a,我们具有函数类型a -> a,该函数的类型可以接受任何类型的参数a并产生具有相同类型的结果,并带有约束{ {1}},实际上意味着该函数只能与实现Floating a类型类的类型一起使用。

答案 2 :(得分:0)

->是函数的构造函数,=>用于约束,这是Haskell中的一种称为“接口”的类型类。

一个小例子:

sum :: Int -> Int -> Int
sum x y = x + y

该函数仅允许使用Int类型,但是如果您想要一个大int或一个小int,则可能需要Integer,以及如何告诉它同时使用两者?

sum2 :: Integral a => a -> a -> a
sum2 x y = x + y

现在,如果您尝试这样做:

sum2 3 1.5

它会给你一个错误

另外,您可能想知道两个数据是否相等:

equals :: Eq a => a -> a -> Bool
equals x y = x == y

现在是否可以:

3 == 4

没关系

但是,如果您创建:

data T = A | B

equals A B

它将给您:

error:
    • No instance for (Eq T) arising from a use of ‘equals’
    • In the expression: equals A B
      In an equation for ‘it’: it = equals A B

如果您希望它能正常工作,则必须执行以下操作:

data T = A | B deriving Eq

equals A B

False