使用只有两个参数的 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
我有一些练习准备 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