[英]Haskell function composition methods
我剛開始在uni學習Haskell,在玩耍時,偶然發現了一個我似乎無法理解的問題。 以下代碼給了我想要的結果:
import Data.List
list = ["Hello", "world"]
main = print $ intercalate " something " (reverse (map reverse list))
輸出:
"dlrow something olleH"
但是我想用點而不是方括號來寫“ main”函數,所以它嘗試了:
main = print $ intercalate " something " . reverse . map reverse list
但是,這給了我以下錯誤:
test.hs:5:54: error:
• Couldn't match expected type ‘a0 -> [[Char]]’
with actual type ‘[[Char]]’
• Possible cause: ‘map’ is applied to too many arguments
我認為這些點的含義與括號完全相同:功能組成。 括號為什么起作用,而點給我一個與類型相關的錯誤? 任何幫助將不勝感激!
功能組成的等效性如下:
main = print (intercalate " something " (reverse (map reverse list)))
main = print (intercalate " something " ((reverse . map reverse) list))
main = print ((intercalate " something " . (reverse . map reverse)) list)
main = (print . (intercalate " something " . (reverse . map reverse))) list
或者,通過刪除不必要的括號:
main = (print . intercalate " something " . reverse . map reverse) list
main = print . intercalate " something " . reverse . map reverse $ list
在您的嘗試中, map reverse list
是單個表達式,即infix的參數.
運算符,它不起作用-您只能組成map reverse
函數,然后將整個組合函數應用於list
參數。
括號並不意味着功能組成。 他們只是意味着“將這個子表達式分組”。 當然,您可以使用它們來構成功能組合鏈:以下將c
定義為功能f
, g
和h
c x = f (g (h x))
也可以寫成:
c = f . g . h
因此,您可以編寫
main = print $ c list
where c = intercalate " something " . reverse . map reverse
但是,如果您再次內聯c
,則需要注意不要弄亂解析規則:僅在該組成鏈的右邊寫入list
不會做,因為函數應用程序比任何infix運算符(包括.
實際上是最嚴格的中綴運算符)。 即
intercalate " something " . reverse . map reverse list
實際上被解析為
(intercalate " something ") . (reverse) . (map reverse list)
但這不是您想要的。 您需要確保list
實際上是整個組合鏈的參數,而不僅僅是其最后一個元素。 首選的方法是使用$
運算符:
intercalate " something " . reverse . map reverse $ list
$
具有最低的普遍性,因此將其解析為
((intercalate " something ") . (reverse) . (map reverse)) (list)
另外,您可以立即將map reverse
應用於list
-這本身沒有錯,只是結果不再是組成鏈的一部分:
intercalate " something " . reverse $ map reverse list
使用.
表示該函數將有另一個參數。 如果您改為編寫以下內容,則它將起作用。
main = print $ (intercalate " something " . reverse . map reverse) list
這樣, list
值是括號內組成的函數的參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.