[英]Haskell - Apply list of functions to a variable
我一直在尝试实现一个函数,它将作为参数给出的函数列表应用于给定变量。 我一直在遇到各种类型错误,包括无限类型和类型不匹配。 下面是使用递归的草稿,我认为它接近工作,但继续运行以键入不匹配。 我很难陷入这个问题的沼泽,不知道如何取得进展。
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
看起来您正在尝试编写两个不同的函数。 让我们分别看看它们。 如果你想要这个签名,
applyList :: [a -> b] -> a -> [b]
然后您想将每个函数应用于输入并获取结果列表。 你不需要一个 lambda。 您可以在递归的每一步简单地将f
应用于变量。
applyList :: [a -> b] -> a -> [b]
applyList [] _ = []
applyList (f:fs) variable = f variable : applyList fs variable
现在,Haskell 提供了许多用于处理列表和数据结构的高级运算符,因此这种显式递归并不像您想象的那么频繁。 特别是,您的applyList
实际上只是map
函数。
applyList :: [a -> b] -> a -> [b]
applyList fs a = map (\f -> f a) fs
并且\f -> fa
可以短接到操作符部分
applyList :: [a -> b] -> a -> [b]
applyList fs a = map ($ a) fs
现在是第二个。 如果这是你的目标
applyList :: [a -> a] -> a -> a
那么你想要弃牌是对的。 根据您的示例输入和输出,您似乎希望首先应用最右边的函数,因此我们可以使用foldr
实现它
applyList :: [a -> a] -> a -> a
applyList fs a = foldr (\f a -> f a) a fs
同样, \fa -> fa
只是一种可爱的书写方式($)
applyList :: [a -> a] -> a -> a
applyList fs a = foldr ($) a fs
如果您现在还不清楚,请不要担心。 如果您对此更满意,请坚持使用您的递归定义。 这种更高层次的思考伴随着在 Haskell 中的时间和经验,如果你继续做你正在做的事情,我保证你会到达那里。
请记住,列表的第一个元素应该是最外层的函数,这意味着您不需要向后执行任何操作或使用foldl
。 明确地写出来,它会是这样的:
applyList [] variable = variable
applyList (f:fs) variable = f (applyList fs variable)
并使用foldr
:
applyList = foldr (.) id
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.