所以这个问题很简单,但我似乎无法理解这个概念。
要编写普通函数,只需执行如下操作:
lowerNoSpaces = filter (/= ' ') . map toLower
但是,有时这不起作用:
myConcatMap = concat . map
它给出了错误:
<interactive>:236:1: error:
* Non type-variable argument
in the constraint: Foldable ((->) [a1])
(Use FlexibleContexts to permit this)
* When checking the inferred type
concattMap :: forall a1 a2.
Foldable ((->) [a1]) =>
(a1 -> a2) -> [a2]
但是当同一个函数表达成这样时:
myConcatMap = (concat .) . map
它完全按照预期工作。
我知道这是有原因的,但我已经盯着它看了有一段时间了,仍然不太明白为什么原来的不起作用,而这个却起作用。
为什么有两个“.”的?
从定义中很容易得出这一点(.)
以及 Haskell 语法的知识。
您从更明确的定义开始myConcatMap
,即
\f -> \xs -> concat (map f xs)
根据复合运算符的定义,您可以将其写为
\f -> concat . (map f)
使用重写这个.
在前缀位置而不是作为中缀运算符。
\f -> (.) concat (map f)
并添加一些多余的括号,因为函数应用程序是左关联的。
\f -> ((.) concat) (map f)
使用节语法重写它以使得.
又是一个中缀运算符
\f -> (concat .) (map f)
并应用定义(.)
再一次,使用函数(concat .)
and map
:
(concat .) . map
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)