繁体   English   中英

Haskell - 将函数列表应用于变量

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM