Mel*_*met 1 haskell functional-programming
我一直在尝试实现一个函数,该函数将作为参数给出的函数列表应用于给定变量。我遇到了无限类型和类型不匹配的各种类型错误。下面是使用递归的草稿,我相信已经接近工作,但继续遇到类型不匹配的情况。我陷入了这个问题的泥潭,不知道如何取得进展。
applyList :: [a -> b] -> a -> [b]
applyList [] variable = variable
applyList (f:fs) variable = applyList fs $(\f variable -> f variable)
Run Code Online (Sandbox Code Playgroud)
这是我使用 Foldl 的另一个草稿解决方案,也没有成功。
applyList :: [a -> a] -> a -> a
applyList fs variable = foldl (\variable f -> f variable) variable fs
Run Code Online (Sandbox Code Playgroud)
用法示例:
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
Run Code Online (Sandbox Code Playgroud)
看起来您正在尝试编写两个不同的函数。让我们分别来看一下。如果你想要这个签名,
applyList :: [a -> b] -> a -> [b]
Run Code Online (Sandbox Code Playgroud)
然后您想要将每个函数应用于输入并获取结果列表。你不需要 lambda。您可以简单地f在递归的每一步应用该变量。
applyList :: [a -> b] -> a -> [b]
applyList [] _ = []
applyList (f:fs) variable = f variable : applyList fs variable
Run Code Online (Sandbox Code Playgroud)
现在,Haskell 提供了许多高级运算符来处理列表和数据结构,因此这种显式递归并不像您想象的那么频繁。特别是,你的applyList确实只是map函数。
applyList :: [a -> b] -> a -> [b]
applyList fs a = map (\f -> f a) fs
Run Code Online (Sandbox Code Playgroud)
并且\f -> f a可以短接至操作员部分
applyList :: [a -> b] -> a -> [b]
applyList fs a = map ($ a) fs
Run Code Online (Sandbox Code Playgroud)
现在是第二个。如果这是你的目标
applyList :: [a -> a] -> a -> a
Run Code Online (Sandbox Code Playgroud)
那么你想要弃牌是对的。根据您的示例输入和输出,您似乎希望首先应用最右边的函数,因此我们可以使用foldr
applyList :: [a -> a] -> a -> a
applyList fs a = foldr (\f a -> f a) a fs
Run Code Online (Sandbox Code Playgroud)
再说一次,\f a -> f a这只是一种可爱的写作方式($)
applyList :: [a -> a] -> a -> a
applyList fs a = foldr ($) a fs
Run Code Online (Sandbox Code Playgroud)
如果您现在还不清楚,请不要担心。如果您对此更满意,请坚持使用您的递归定义。这种更高层次的思考伴随着 Haskell 的时间和经验而来,如果你继续做你正在做的事情,我保证你会到达那里。