簡體   English   中英

如何在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM