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

标签 haskell

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

我都看过->=> .

举个例子:我可以做我自己的类型声明。

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

它工作得很好。

但是如果我们看一下 :t sqrt我们得到:
sqrt :: Floating a => a -> a

我们在什么时候使用=>我们什么时候使用-> ?
我们什么时候用“肥箭”,什么时候用“细箭”?

最佳答案

->用于显式函数。 IE。当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 的一个实例类(class)。需要此类约束的地方是类型不是固定的而是类型变量(即小写),即如果函数是多态的。你不能只写
addMe' :: a -> a -> a
addMe' x y = x + y

因为该签名表明该函数适用于任何类型 a无论如何,但它不能适用于所有类型(例如,您将如何添加两个字符串?好吧也许不是最好的例子,但是您将如何将两个字符串相乘?)

因此,您需要约束
addMe' :: Num a => a -> a -> a
addMe' x y = x + y

这意味着,您不必关心确切的类型 a是,但您确实要求它是数字类型。任何人都可以在自己的类型中使用该函数MyNumType ,但他们需要确保 Num MyNumType满足:那么addMe'可以有签名MyNumType -> MyNumType -> MyNumType .

确保这一点的方法是使用您知道是数字的标准类型,例如 addMe' 5.9 3.7 :: Double会起作用,或者为您的自定义类型和 Num class 提供实例声明.如果您确定这是一个好主意,请仅执行后者;通常,您只需要标准的 num 类型。

†请注意,箭头在签名中可能不可见:函数类型可能有类型同义词,例如当 type IntEndofunc = Int -> Int ,然后 f :: IntEndofunc; f x = x+x没关系。但是你可以认为 typedef 本质上只是一个语法包装器;它仍然是同一类型,并且确实有箭头。

‡巧合的是,逻辑蕴涵和函数应用可以看作是同一数学概念的两个方面。此外,GHC 实际上将类约束实现为函数参数,即所谓的字典。但所有这些都发生在幕后,所以如果有的话,它们是隐式函数。在标准 Haskell 中,您永远不会看到 => 的 LHS type 作为函数应用到的一些实际参数的类型。

关于haskell - -> 和 => 符号之间的区别。他们的意思是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56761514/

相关文章:

haskell - 创建 Xmonad 配置时使用 IO(键盘映射取决于连接的监视器数量)

haskell - 您如何从 lambda 术语转换为交互网络?

haskell - Haskell 是否有某种数字转换为科学格式?

mysql - 使用 MySQL 和 Yesod 的持久语法错误

configuration - 如何管理单个 Haskell 程序的多个配置?

haskell - 并发程序中IORef操作重排序的推理

haskell - 寻找组合

haskell - 对方法的约束取决于范围内的实例?

Haskell:使用列表理解解析错误(可能是不正确的缩进或不匹配的括号)

haskell - 在haskell中记录具有多个构造函数的类型