2016-03-02 21 views
0

我只知道Haskell「。」可以用來組合功能,所以我試過:映射2函數組合失敗:語法錯誤?

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" 

那麼如何糾正我的情況呢?謝謝。

+0

你不能這樣做,原因很簡單:'++「x」'不是表達式。相反,'(++「x」)'*是一個表達式。 – user2407038

回答

3

你正在做的東西的名字時,你說(++ "world")的是,你所使用的是稱爲「部分應用中綴運算符」的「右部分」:

https://wiki.haskell.org/Section_of_an_infix_operator

這對(++ "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"] 

FYI:如果你想組成爲:以相反的順序(世界第一,那麼XYZ),你可以使用>>>從Control.Arrow

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

中綴運算符像圓括號。

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

++是中綴操作符,以及你如何使用它的規則比的正常功能不同。

你可以用它夾在兩個值之間,這樣

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) 

將工作