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

What is the meaning of parentheses in Haskell type signatures?

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

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

这与以下类型签名有何不同?

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

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

是的,

(a -> b) -> ...

表示"given a function which takes a to b ..."。而这

a -> b -> ...

表示"given some a and some b..."

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

是的,有区别,因为the -> type constructor is right-associative。也就是说,

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

相当于

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

此类型签名表示一个函数,该函数采用 a 类型的参数,returns 函数本身采用 b 和 returns 类型的参数函数,它本身采用 f a 类型的参数和 returns 类型的值 f b.

另一方面,

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

表示接受类型 a -> b 参数的函数(即接受类型 a 参数和 returns 类型值 b 的函数)和 returns 一个函数,它本身接受一个 f a 类型的参数和 returns 一个 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]