2015-02-08 162 views
4

我寫了一個函數,它將函數列表應用於一個項目。在Haskell中應用函數列表

applyAll :: [a -> b] -> a -> [b] 
applyAll [] _ = [] 
applyAll (f:fs) x = (f x) : (applyAll fs x) 

有沒有更好的方法來做到這一點?

回答

8

你可以使用:

applyAll l v = fmap ($ v) l 

fmap在輸入列表(實際上任何函子)提升的功能。 $的類型爲(a -> b) -> a -> b,因此它將函數應用於給定值。 ($ v)section,它將給定的函數應用於v

+5

當這樣豈不更好了明確的遞歸方法嗎?它更優雅,更簡潔,更通用,可能更易於優化,可以在任何地方進行特定內聯定義... – leftaroundabout 2015-02-09 00:02:56

6

李的解決辦法是什麼我建議,但這種讀取甚至更好:

import Control.Applicative 

applyAll' fs v = fs <*> pure v 

applyAll'' fs v = fs <*> [v] 

這類品牌的東西比需要更復雜,雖然:我們真的只需要列表的Functor實例,而applyAll'會注入並立即從Applicative實例中提取。

+0

這種特殊的等價性確實幫助我在幾個月前考慮過某些事情。 – dfeuer 2015-02-09 04:59:03

18

這個函數實際上已經存在的一元函數的一個特例:

applyAll :: [a -> b] -> a -> [b] 
applyAll = sequence 
+4

可能值得指出的一點是,當你把'f'變成'(a - 1)'時,'[fb] - > f [b]'與'[a - > b] - >(a - > [b] >)'。 (不要錯過它不是有效的語法,它會得到最好的結果。) – Carl 2015-02-09 01:02:59

+1

@Carl,我從來不明白爲什麼這不是有效的語法。 – dfeuer 2015-02-09 03:32:26

+0

李在某些情況下可能會更有效率,但是這種方法在獲得圖書館功能方面已經具備了一定的作用。 – dfeuer 2015-02-09 03:34:50