对于作业我正在处理函数列表[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)
这实际上有效。在文件中还有一段错误的代码,对不起大惊小怪。
答案 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
的列表,其中包含第一个列表中应用于第二个参数的每个函数的结果。