![](/img/trans.png)
[英]How does function application with the $ operator curry in Haskell?
[英]How to curry function with two parameters in Haskell
我有一個類型為Integral a => [a] -> Int -> Int -> [[a]]
的函數buckets
,我想以這種方式在foldl
中使用它:
basketsort lst = foldl (f) lst [1..3]
f lst = reverse . concat . (flip buckets 9) lst
函數f
起作用,並且具有類型Integral a => [a] -> Int -> [a]
,但是如果我減少lst
參數,則編譯將失敗。
是否可以通過遞歸減少多個參數並在不聲明f
情況下在折疊中使用f
的主體? 像這樣:
basketsort lst = foldl (reverse . concat . (flip buckets 9)) lst [1..3]
如果展開點運算符的第二個應用程序:
f lst = reverse . concat . (flip buckets 9) lst
==> f lst = (.) (reverse . concat) ((flip buckets 9) lst)
那么eta減少就變得很明顯:
f = (.) (reverse . concat) . (flip buckets 9)
但是,來吧,您真的要這樣做嗎? 對於離開后要維護代碼的人來說,這不是一個很好的禮物。
第一:我建議不要僅使用flip
來將函數部分地應用於第二個參數; 使用infix部分可以更好地做到這一點。 (或者,也許bucket
的爭論首先應該是相反的?)
所以,你想
f lst = reverse . concat . (`buckets`9) lst
沒有意義。 問題是您需要將兩個參數傳遞給組成鏈中最右邊的元素。 一種實現方法是使用非咖喱形式(因為這兩個參數只是一個值):
f = curry $ reverse . concat . uncurry (`buckets`9)
一種替代方法是使用專用的組合器。 pointless-fun
包具有以下內容 :
f = reverse . concat .: (`buckets`9)
盡管IMO相當丑陋,但更標准的方法是使用function-functor:您可以映射一個函數,這相當於在其后進行編寫:
f = fmap (reverse . concat) . (`buckets`9)
坦率地說,最好的選擇是將該參數命名為:
basketsort lst = foldl (\l -> reverse . concat . buckets l 9) lst [1..3]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.