我一直在尝试实现一个函数,它将一系列函数作为参数应用于一个给定的变量。我遇到了各种类型错误,类型无限多,类型不匹配。下面是使用递归的草稿,我相信它已经接近工作了,但是不断遇到类型不匹配。我被困在这个问题的沼泽里,不知道如何前进。
applyList :: [a -> b] -> a -> [b]
applyList [] variable = variable
applyList (f:fs) variable = applyList fs $(\f variable -> f variable)
这是我的另一个使用foldl的解决方案草案,也没有成功。
applyList :: [a -> a] -> a -> a
applyList fs variable = foldl (\variable f -> f variable) variable fs
示例用法:
applyList [] "foo" ==> "foo"
applyList [] 1 ==> 1
applyList [(++"bar")] "foo" ==> "foobar"
applyList [reverse, tail, (++"bar")] "foo" ==> "raboo"
applyList [(3*), (2^), (+1)] 0 ==> 6
applyList [(+1), (2^), (3*)] 0 ==> 2
2条答案
按热度按时间htrmnn0y1#
看起来您要编写两个不同的函数。让我们分别看一下它们。如果您需要此签名,
然后你想把每个函数应用于输入并得到一个结果列表。你不需要lambda。你可以简单地在递归的每一步把
f
应用于变量。现在,Haskell提供了很多高级运算符来处理列表和数据结构,所以这种显式递归并不像你想象的那么频繁,特别是,你的
applyList
实际上就是map
函数。\f -> f a
可以短接至operator section现在是第二个。如果这是你的目标
那么您需要一个fold是正确的。基于您的示例输入和输出,您似乎希望首先应用最右边的函数,因此我们可以使用
foldr
来实现它同样,
\f a -> f a
只是($)
的一种可爱写法如果你现在还不清楚,不要担心。如果你对递归定义更熟悉的话,可以坚持使用它。这种更高层次的思考需要时间和经验,如果你坚持做你正在做的事情,我保证你会做到的。
xdyibdwo2#
记住列表的第一个元素应该是最外层的函数,这意味着你不需要向后做任何事情或者使用
foldl
。显式地写,它应该是这样的:与
foldr
一起: