Haskell 类型签名中括号的含义是什么?
What is the meaning of parentheses in Haskell type signatures?
以fmap
(Functor
方法)的类型签名为例:
(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]
以fmap
(Functor
方法)的类型签名为例:
(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]