递归地使用类似 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
即:如果列表为空,那么我们return在第二个位置的累加值。否则,我们计算新的累加值 (fn c x
),然后将其作为第二个参数传递给我们的函数,同时转发 fn
并传递列表的其余部分。
作为练习,我正在尝试编写一个与 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
即:如果列表为空,那么我们return在第二个位置的累加值。否则,我们计算新的累加值 (fn c x
),然后将其作为第二个参数传递给我们的函数,同时转发 fn
并传递列表的其余部分。