Haskell:已知f::a->b,求map (.f)的类型及相关疑问
Haskell类型推导:
map (.f)的解析 已知f :: a -> b,我们来拆解map (.f)的类型推导,解答你的两个疑问:
疑问1:为何输入类型是[b -> c]而非(b -> c)?
先明确map的核心作用:它是列表映射函数,类型为map :: (x -> y) -> [x] -> [y]。也就是说,它需要两个参数:
- 第一个是单个函数
x->y,用来处理列表中的每个元素 - 第二个是元素类型为
x的列表,最终返回元素类型为y的列表
接下来看(.f)的类型:
函数组合运算符(.)的类型是(b -> c) -> (a -> b) -> a -> c,它的作用是把两个函数拼接成新函数:g . f = \x -> g (f x)。当我们写成.f时,是对(.)做部分应用——固定了它的第二个参数为f,推导后得到:
(.f) :: (b -> c) -> a -> c
这个新函数的作用是:接收一个函数g :: b->c,返回g . f(也就是先执行f,再执行g的组合函数)。
现在把(.f)代入map的第一个参数位置:
map的第一个参数类型x->y对应(.f)的类型(b -> c) -> a -> c,所以x = b -> c,y = a -> c- 那么
map的第二个参数(也就是map (.f)的输入)就是[x] = [b -> c],返回值是[y] = [a -> c]
说白了,map (.f)是把列表里的每个函数都和f做组合,所以它需要接收一个函数列表,而不是单个函数。如果是单个函数,直接用(.f)本身就够了。
疑问2:.f的含义,以及和map . f的区别
.f的本质
.f是函数组合运算符(.)的部分应用写法,等价于\g -> g . f。它是一个高阶函数:接收一个函数g,返回g和f的组合函数g . f。
和map . f的区别
map . f是另一种函数组合,等价于(.) map f,它的作用和map f完全一致。推导一下类型:
map :: (x->y) -> [x] -> [y]f :: a -> b- 组合后
map . f :: [a] -> [b],也就是接收a类型的列表,返回b类型的列表。
简单总结:
.f:生成一个“和f组合”的函数map . f:把f映射到列表的每个元素上
内容的提问来源于stack exchange,提问作者selfPointer
相关产品推荐
相关产品推荐

