使用只有两个参数的 foldr

Using foldr with only two parameters

我有一些练习准备 Haskell/Prolog 中的考试。

一个Haskell任务是重写下面的函数:

original :: [Integer] -> Integer
original [] = 0
original (x:xs) | x < 20    = 5 * x - 3 + original xs
                | otherwise = original xs

但条件是我只能去掉下面方案中的两个"undifined":

alternative :: [Integer] -> Integer
alternative = foldr undefined undefined

我的问题是我不知道这如何匹配具有 3 个参数的普通文件夹结构(函数,"start value" 或者它是如何调用的?,列表)?

也许等效的示例会有所帮助,但请不要提供完整的答案!

此外,我不允许使用 "let" 或 "where"。

感谢您的帮助!

Sooo...我只是按照@hugo 的想法首先以 "normal" 方式完成任务,这种方式可行但我们的大学批改工具不允许:

alternative :: [Integer] -> Integer
alternative list = foldr (\ x y -> if x < 20 then 5*x -3 + y else y) 0 list

并且在尝试结束错误后我得到了解决方案:

alternative :: [Integer] -> Integer
alternative = foldr (\ x y -> if x < 20 then 5*x -3 + y else y) 0

[1,4,2,5] 这样的列表是 (:) 1 ((:) 4 ((:) 2 ((:) 5 []))) 的语法糖。 foldr f z 基本上将 (:) 数据构造函数替换为 f,并将空列表数据构造函数 [] 替换为 z。所以 foldr f z 将导致 f 1 (f 4 (f 2 (f 5 z))).

既然你写的是original [] = 0,这就意味着对于z,我们可以使用0。对于 f 我们可以使用 if x < 20 then (+) (5*x-3) else id,因为在 x < 20 的情况下,我们将 5*x-3 添加到该值,否则,我们对递归计算的值不做任何事情。

因此我们可以alternative实现如下所示:

alternative :: (Foldable  f, Num a, Ord a) => f a -> a
alternative = foldr f 0
    where f x ys | x < 20 = 5*x - 3 + ys
                 | otherwise = ys

或不带内联 lambda 表达式的 where 子句:

alternative :: (Foldable  f, Num a, Ord a) => f a -> a
alternative = foldr (\x -> if x < 20 then (+) (5*x-3) else id) 0