Haskell将单个值应用于函数列表

时间:2014-11-22 17:58:25

标签: haskell

对于作业我正在处理函数列表[Int -> Int](例如[(+3), (*4), (+1)]),我想对每个函数应用一个Int,然后创建一个结果列表[Int]

我已经搜索了很多,但我找不到办法进行这样的操作。使用map无法正常工作。相关的错误是:

ERROR - Cannot infer instance
*** Instance   : Num ((Label -> Label) -> a)

按要求提供代码:

data Tree = Node (Label -> Label) Label [Tree]
type Label = Int

testTree = Node (+1) 3 [ Node (+1) 5 [], Node (+1) 4 [Node (+1) 1 [], Node (+2) 7 []]]

listify :: Tree -> [(Label -> Label)]
listify t = [(getNodeFunction t)] ++ concat(map (listify) (getSubTrees t))


*Main> map (\f -> f 7) (listify testTree)

这实际上有效。在文件中还有一段错误的代码,对不起大惊小怪。

5 个答案:

答案 0 :(得分:29)

您可以使用代表功能应用的$运算符。

> map ($ 3) [(+3), (*4), (+1)]
[6,12,4]

这基本上扩展为[(+3) $ 3, (*4) $ 3, (+1) $ 3],这只是功能应用。

答案 1 :(得分:3)

如果flist是函数列表且x是参数,则需要map (\f -> f x) flist

例如

Prelude> map (\f -> f 10) [(4 +), (3 *)]
[14,30]

答案 2 :(得分:3)

基本上,这是一个应用性工作。您可能会喜欢

λ> [(+3), (*4), (+1)] <*> pure 3 -- or [3]
[6,12,4]

答案 3 :(得分:2)

我知道这个问题有点老了,但是我觉得应该提到sequence

> sequence [(+3), (*4), (+1)] 3
[6,12,4]

(如今,sequenceA被认为是sequence的现代替代品;每当进行两次类型检查时,它都具有相同的行为,但是在更多情况下进行类型检查。但是,这里没有区别,所以我喜欢这个名称的噪音略小。)

答案 4 :(得分:0)

您也可以使用list comprehension。该行足以满足您的示例:

[ f 3 | f <- [(+3), (*4), (+1)] ]

这会将右侧列表中的每个函数应用于左侧的值(在这种情况下为3)。


对于更通用的版本,这可能会有所帮助:

applyFuns :: [(a->b)] -> a -> [b]
applyFuns fs x = [ f x | f <- fs ]

applyFuns [(+3), (*4), (+1)] 3

函数applyFuns将类型a->b中的函数列表作为第一个,并将类型b的值作为第二个。结果是类型为b的列表,其中包含第一个列表中应用于第二个参数的每个函数的结果。