使用 fold 计算范围内的数字

问题描述

我有一个任务:

使用 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 是要处理的列表。
  • 第二个 accxs 为空时的结果。
  • 第一个 f 是用于将 accxs 的元素依次组合的函数。

由于 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)

对于您的情况,希望很清楚您需要 xsxs(因为这是您需要处理的列表),并且您需要 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 的解决方案就会变得更容易。