【发布时间】:2019-08-04 23:33:40
【问题描述】:
我有一些练习来准备 Haskell/Prolog 中的考试。
Haskell 的一个任务是重写下面的函数:
original :: [Integer] -> Integer
original [] = 0
original (x:xs) | x < 20 = 5 * x - 3 + original xs
| otherwise = original xs
但条件是我只允许删除下面方案中的两个“未定义”:
alternative :: [Integer] -> Integer
alternative = foldr undefined undefined
我的问题是我不知道这如何匹配具有 3 个参数(函数、“起始值”或如何调用的?、列表)的普通 foldr 结构?
也许一个等效的例子会有所帮助,请不要完整的灵魂!
此外,我不允许使用“let”或“where”。
感谢您的帮助!
Sooo...我只是按照@hugo 的想法首先以“正常”方式完成任务,这有效但我们的大学校正工具不允许:
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
【问题讨论】:
-
提示:
foldr是列表中的某种变态:您可以将(:)替换为第一个参数,将[]替换为第二个参数,然后得到@ 的结果987654328@. -
部分应用/柯里化意味着每当你将一个函数应用到一个参数上时,你会得到一个带有剩余参数的函数。
foldr有(a -> b -> b) -> b -> [a] -> b类型,所以如果你给它两个参数(适当的类型)你会得到一个类型为[a] -> b的函数,它与你在这里想要得到的匹配。 -
忽略一些细微之处,
alternative = foldr undefined undefined等价于alternative x = foldr undefined undefined x。 -
@rene:你如何开始编写
alternative函数,忽略你提到的参数约束?将其添加到您的问题中,人们会从那里帮助您(除非您一路弄清楚,这很可能发生!) -
@rene 是的,你需要了解柯里化和偏应用。关键思想是所有函数,包括
foldr,都采用 one 参数。其中一些碰巧返回另一个函数,因此可以接受另一个参数,依此类推。这里foldr将a->b->b作为参数,并返回b->[a]->b。如果将另一个b类型的参数应用于结果,那么我们会得到另一个[a]->b类型的结果,它与alternative的类型匹配。