map 2 函数组合失败:语法错误?

map 2 function combination fails: syntax error?

我只知道在Haskell“.”可以用来组合函数,所以我试了:

Prelude> map (++" world")["hello","abc"]
["hello world","abc world"]
Prelude> map (++" world". ++"xyz")["hello","abc"]

<interactive>:3:18: parse error on input `++'

为什么我不能这样做?我试过命名函数,没问题:

Prelude> map (head.tail)["hello","abc"]
"eb"

那么如何纠正我的情况呢?谢谢

像括号一样的中缀运算符。

Prelude> map ((++ " world") . (++ "xyz")) ["hello", "abc"]

++是一个中缀运算符,使用规则与普通函数不同。

您可以像这样将它夹在两个值之间使用

x ++ y

或使用括号将其转换为普通函数

(++) x y --same as above

有两种方法可以将值部分应用于中缀运算符

(x ++) --same as \y -> x ++ y
(++ y) --same as \x -> x ++ y

这两个都需要外括号,否则 Haskell 会尝试将表达式解析为正常的中缀大小写

++ x . ++ y -- will confuse the parser

但是

(++ x) . (++ y)

会工作

当你说 (++ "world") 时你正在做的事情的名称是你正在使用所谓的 "right section" of a "partially applied infix operator":

https://wiki.haskell.org/Section_of_an_infix_operator

这对 (++ "world") 意味着左侧将是生成函数的参数,它将用 "world" 预填充右侧。

所以这不仅仅是为了优先使用括号...这是一种特殊的语法。当您省略第二个 ++ 上的括号时,这意味着您没有调用那里的语法。它试图将其解释为正常的中缀。

如果您想像这样内联组合两个此类函数,请将它们分别放在括号中:

Prelude> map ((++" world") . (++"xyz"))["hello","abc"]
["helloxyz world","abcxyz world"]

注意如果您仅将 ++ 运算符转换为前缀,使用非部分应用的语法对结果的影响:

Prelude> map ((++) " world" . (++) "xyz")["hello","abc"]
[" worldxyzhello"," worldxyzabc"]

您不必将它们分组,但现在您提供第一个参数。您列表的数据在输出的末尾结束。这与在左侧部分使用中缀部分应用程序语法一样:

Prelude> map ((" world" ++) . ("xyz" ++))["hello","abc"]
[" worldxyzhello"," worldxyzabc"]

仅供参考:如果您希望构图的顺序相反(世界第一,然后是 xyz),您可以使用 Control.Arrow

中的 >>>
Prelude> import Control.Arrow
Prelude Control.Arrow> map ((++" world") >>> (++"xyz")["hello","abc"]
["hello worldxyz","abc worldxyz"]