递归地使用类似 foldl 的函数

Using a Function Like foldl Recursively

作为练习,我正在尝试编写一个与 foldl 函数行为相同的函数,并且我也在尝试使用递归。

我的函数将被调用,"leftFolder" 并且签名看起来像 foldl 函数的: leftFolder :: (a -> b -> a) -> a -> [b] -> a

我有点不知道该怎么做,但这是我尝试过的:

leftFolder :: (a -> b -> a) -> a -> [b] -> a
leftFolder [] = []
leftFolder (x:xs) = x (++) (leftFolder xs)

在我看来,这是有道理的。我是说如果列表是空的,return 是一个空列表。如果不是,则取列表的头部,然后继续将其附加到尾部。

你的代码有很多问题。例如:

  • 你将模式匹配作为第一个参数[]而第一个参数应该是一个函数
  • 您只使用了 1 个参数,而不是您需要的 3 个参数
  • x (++) ... 没有意义;你可能打算使用 x:...
  • 在第一个模式匹配中,您 return 正在创建一个列表,而您函数的 return 类型不一定是列表

我相信你要找的是这个:

leftFolder :: (a -> b -> a) -> a -> [b] -> a
leftFolder _ c [] = c
leftFolder fn c (x:xs) = leftFolder fn (fn c x) xs

Live demo

即:如果列表为空,那么我们return在第二个位置的累加值。否则,我们计算新的累加值 (fn c x),然后将其作为第二个参数传递给我们的函数,同时转发 fn 并传递列表的其余部分。