如果我有一個函數列表,某種類型的每個a -> a
類型,什麼是最短,最優雅和慣用的方法將它們結合起來;最好不添加額外的依賴?[a - > a] - >(a - > a)的最慣用的實現`
一些變體包括
foo (x:xs) = x . (foo xs)
foo [] = id
和
foo = foldr (.) id
和
foo = appEndo . mconcat . map Endo
,但由於某種原因,我希望找到的東西更好。
如果我有一個函數列表,某種類型的每個a -> a
類型,什麼是最短,最優雅和慣用的方法將它們結合起來;最好不添加額外的依賴?[a - > a] - >(a - > a)的最慣用的實現`
一些變體包括
foo (x:xs) = x . (foo xs)
foo [] = id
和
foo = foldr (.) id
和
foo = appEndo . mconcat . map Endo
,但由於某種原因,我希望找到的東西更好。
我說你不會打
comp = foldr (.) id
爲什麼?那麼我們有一個列表,我們試圖以正確的關聯方式來減少它。
如果你看看and
,sum
,maximum
和類似的實現,你會看到,這是他們如何在標準庫中實現的,我不認爲你比獲得更地道:)
切線:我不願意添加評論中提到的foldr1
變體,因爲我認爲這是意想不到的行爲,因爲這是不完整的,不像maximum
這顯然是必須的。
如果我看看'和','sum','maximum'和類似的實現,我想知道爲什麼沒有'foldr(。)id'的名字呢,然後;-) –
@JoachimBreitner這不是一個壞問題: )不幸的是,除了「可能是偶然的機會」之外,我沒有任何答案 – jozefg
再一個,這可能不是短於foldr (.) id
,但我認爲這是可愛:(。)
foo = flip (foldr id)
對於最初感到困惑的人(像我),使用'id'作爲類型'a - > b - > b'的函數會將'a'類型與類型'b - > b'。所以foldr id(foldr的類型是('a - > b - > b) - > b - > [a] - > b'),具有類型'b - > [b - > b] - > b'等等'flip(foldr id)'具有類型'[c - > c] - > c - > c'這與'[c - > c] - >(c - > c)'相同' – Squidly
欲瞭解更多詳情,使用'id'通常被稱爲'($)'。 '($)'只是一個更具體類型的'id'('(a - > b) - > a - > b'而不是'a - > a')。我相信他在這裏使用'id',因爲它更短。當寫出來時,這個解決方案可以寫成'foo l x = foldr($)x l'。這可以讓你看到發生了什麼,例如'foo lx = l1 $ l2 $ l3 $ l4 $ .. ln $ x',這當然與'(l1。l2。l3。l4。.. ln )x'這是jozefg的解決方案。 – newacct
'foldr相似id'沒有? – jozefg
當然可以。 –
你想要與'foldr'版本有什麼不同?它有12個字符,不完全長,清晰,並且沒有依賴關係,並且抽象了遞歸的所有細節。 – jozefg