Haskell类型签名中括号的含义是什么?

23

fmapFunctor方法)的类型签名为例:

(a -> b) -> f a -> f b

这与以下类型标记有何不同?

a -> b -> f a -> f b

这两种类型签名之间是否有区别?


2
文本中的问题与标题中的问题有何关联?类型签名中的括号并不表示特殊语义,而是用于优先级,就像 Haskell 中的其他地方一样,这就是为什么这两个代码片段不相等的原因。 - Jörg W Mittag
2
@JörgWMittag:我同意这两个问题不是等价的——实际上它们有不同的答案——但我很惊讶你认为它们是无关的。它们都涉及到类型签名中括号的含义;对标题中问题的肯定回答可能会导致对文本中问题的肯定回答;而对任何一个问题的好回答可能会隐含地(甚至明确地)回答另一个问题。 - ruakh
2
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Jörg W Mittag
3个回答

33

是的,存在区别,因为 -> 类型构造器是右结合的。换句话说,

a -> b -> f a -> f b

等同于

a -> (b -> (f a -> f b))

这种类型签名表示一个接受类型为a的参数并返回一个函数的函数,该函数本身接受类型为b的参数并返回一个函数,该函数本身接受类型为f a的参数并返回类型为f b的值。

另一方面,

(a -> b) -> f a -> f b

a -> b”表示一个需要以类型 a 为参数并返回类型 b 的函数,它返回一个函数,该函数本身需要以类型“f a”为参数并返回类型“f b”的值。

以下是一个人为制造的例子,说明了这两个类型签名之间的区别:

f :: (Int -> Bool) -> [Int] -> [Bool]
f = map

g :: Int -> Bool -> [Int] -> [Bool]
g n b = map (\n' -> (n' == n) == b)

λ> let ns = [42, 13, 42, 17]

λ> f (== 42) ns
[True,False,True,False]

λ> g 42 True ns
[True,False,True,False]

λ> g 42 False ns
[False,True,False,True]

13

是的,

(a -> b) -> ...
意味着“假设有一个将 a 映射到 b 的函数...”。然而,这句话的后半部分缺失。
a -> b -> ...

意思是“给定一些a和一些b……”


6

是的,(a -> b) 表示一个参数,这个参数是一个带有签名 a -> b 的函数;而 a -> b -> ... 表示两个参数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接