问题描述
使用 fold 计算范围内的数字。在函数 numberInRange 下完成,类型为 int list * int * int -> int,它接受三个参数(int list、int、int)并返回一个整数,其数量在 lo 和 hi 之间。
row = {
'EmployeeID' : employeeID,'Department' : department,'LeaveStartDate' : startDate,'LeaveDuration' : duration,'Reason' : reason,'Status' : status,'Remark' : remark
}
谁能告诉我怎么做,我正在努力解决我的作业问题
解决方法
fold
接受三个参数,最容易以相反的顺序解释:
- 第三个
xs
是要处理的列表。 - 第二个
acc
是xs
为空时的结果。 - 第一个
f
是用于将acc
与xs
的元素依次组合的函数。
由于 fold
的递归性质,一次调用的 f
结果用作下一次调用的 acc
。这是有道理的,因为如果列表的其余部分为空(意味着我们已经到达列表的末尾),则递归调用的 acc
将是结果;所以整体 fold
的结果是最后一次调用 f
的结果。名称 acc
是“累加器”的缩写,但将其视为“部分结果”或“进行中的结果”会有所帮助:它是我们已经处理过的列表部分的结果。
例如:
-
fold f acc []
是acc
-
fold f acc [a]
是f (acc,a)
-
fold f acc [a,b]
是f (f (acc,a),b)
-
fold f acc [a,b,c]
是f (f (f (acc,b),c)
对于您的情况,希望很清楚您需要 xs
为 xs
(因为这是您需要处理的列表),并且您需要 acc
为 {{ 1}}(因为如果 0
为空,这就是您想要的结果)。
所以,只剩下 xs
。请记住,如果 f
是列表的一个元素,并且 x
是所有元素 before acc
之后的结果,那么 x
需要在所有元素 up 到 f (acc,x)
之后给出结果。
因此,在您的情况下,x
需要是“列表中介于 f (6,18)
和 hi
之间的元素数,如果列表以 lo
结尾并且在此之前有 6 个这样的元素。”换句话说,如果 18
在所需的范围内,则它需要为 7
,否则为 18
。你知道怎么做吗?
现在,我应该指出,上面是有时被称为“应试者”的解决方案,利用这样一个事实,即如果没有解决方案,您就不会被分配到这个问题。具体来说,以上假设 6
可以使用 numberInRange
实现,此外,fold
可以通过适当的参数仅作为对 numberInRange
的单个调用来实现。碰巧的是,这个假设是正确的。但是,即使 fold
不能被实现为对 numberInRange
的单个调用(例如,如果某些需要后期处理)——只是答案是错误的!因此,一旦您有了答案,重要的是要检查它以确保它确实按照 fold
应有的方式运行。 (测试一下是个好主意。即使是伟大的 Donald Knuth 也曾写道:“当心上述代码中的错误;我只是证明它是正确的,没有尝试过。”)
虽然您可以使用 fold
来解决此练习,但由于您似乎在尝试之前就卡住了,我建议您改为返回一步并应用列表递归。一次从输入列表中取出一个元素:如果在区间内,则结果加一,否则不加一。
fun numberInRange ([],lo,hi) = ...
| numberInRange (x::xs,hi) =
if ...
then ...
else ...
一些主要问题:
- 什么是空列表的好的返回值?
- 函数应该何时调用自身?
一旦你有了任何一种解决方案,把它变成一个使用 fold
的解决方案就会变得更容易。