2015-02-08 164 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