2013-11-04 46 views
4

如果我有一個函數列表,某種類型的每個a -> a類型,什麼是最短,最優雅和慣用的方法將它們結合起來;最好不添加額外的依賴?[a - > a] - >(a - > a)的最慣用的實現`

一些變體包括

foo (x:xs) = x . (foo xs) 
foo [] = id 

foo = foldr (.) id 

foo = appEndo . mconcat . map Endo 

,但由於某種原因,我希望找到的東西更好。

+8

'foldr相似id'沒有? – jozefg

+0

當然可以。 –

+2

你想要與'foldr'版本有什麼不同?它有12個字符,不完全長,清晰,並且沒有依賴關係,並且抽象了遞歸的所有細節。 – jozefg

回答

19

我說你不會打

comp = foldr (.) id 

爲什麼?那麼我們有一個列表,我們試圖以正確的關聯方式來減少它。

如果你看看andsummaximum和類似的實現,你會看到,這是他們如何在標準庫中實現的,我不認爲你比獲得更地道:)

切線:我不願意添加評論中提到的foldr1變體,因爲我認爲這是意想不到的行爲,因爲這是不完整的,不像maximum這顯然是必須的。

+0

如果我看看'和','sum','maximum'和類似的實現,我想知道爲什麼沒有'foldr(。)id'的名字呢,然後;-) –

+0

@JoachimBreitner這不是一個壞問題: )不幸的是,除了「可能是偶然的機會」之外,我沒有任何答案 – jozefg

6

再一個,這可能不是短於foldr (.) id,但我認爲這是可愛:(。)

foo = flip (foldr id) 
+3

對於最初感到困惑的人(像我),使用'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

+4

欲瞭解更多詳情,使用'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

相關問題