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"]
我只知道在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"]