4

我有一门关于函数式编程的大学课程,我在其中使用 SML。作为考试的准备工作,我正在研究一些没有解决方案的旧考试集。

我真正遇到的唯一问题之一是使用以下问题foldl

考虑程序框架: fun addGt k xs = List.foldl (...) ... xs; 将缺失的两个部分补上(用点...表示),使得 addGt k xs 是 xs 中大于 k 的那些元素的总和。例如,addGt 4 [1, 5, 2, 7, 4, 8] = 5 + 7 + 8 = 20

我确信这真的很容易,但我很难理解 foldl 和 foldr 函数。

我现在拥有的是以下内容(如果您问我的编译器,这似乎是非常错误的!):

fun addGt(k,xs) = List.foldl ( fn x => if x > k then op+ else 0) 0 xs;

我真的很感激这个问题的一些帮助,也许是一个非常简短的评论,可以对foldlandfoldr功能有所了解!

4

2 回答 2

9

我只是想到的一个解决方案如下:

fun addGt(k, xs) = List.foldl (fn (x, y) => if x >= 5  then x + y else y) 0 xs;

但让我解释一下。首先检查List.foldl函数的类型,它是:

('a * 'b -> 'b) -> 'b -> 'a list -> 'b

将另一个类型的函数作为第一个参数List.foldl柯里化函数也是如此('a * 'b -> 'b)。你使用(fn x => if x > k then op+ else 0)了 which 有 type int -> int。相反,您应该提供List.foldl一个函数,该函数接受一个类型的元组int * int并返回一个int,所以像这样:(fn (x, y) => do stuff)。这就是你的代码没有编译的原因,你在foldl.

现在你可以这样想foldl

foldl f b [x_1, x_2, ..., x_(n - 1), x_n] = f(x_n, f(x_(n - 1), ..., f(x2, f(x1, b)) ...))其中f是类型的函数('a * 'b -> 'b)b是类型的东西,'b列表[x_1, x_2, ..., x_(n - 1), x_n]是类型的'a list

类似的,foldr你可以这样想:

foldr f b [x_1, x_2, ..., x_(n - 1), x_n] = f(x_1, f(x_2, ..., f(x_(n - 1), f(x_ n, b))

于 2011-05-11T11:19:26.007 回答
2

如果你调用foldl f s ls一个列表,ls = [x1, x2, ..., xn]那么你会得到结果:

f(xn, ... f(x2, f(x1, s)))

也就是说,它首先找到

a1 = f(x1, s)

然后

a2 = f(x2, a1)

依此类推,直到它通过列表。

完成后,它返回an

您可以将a-values 视为一种累加器,也就是说,ai如果列表只是[x1, x2, ..., xi](或者更确切地说,列表的前 i 个元素),则结果会如此。

您的函数通常具有以下形式:

fn (x, a) => ...

然后你需要做的是想:好的,如果我有列表中的下一个元素x(i+1)和 value ai,这是 list 的结果,[x1, x2, ..., xi]我需要做什么才能找到 value a(i+1),这是结果清单[x1, x2, ..., xi, x(i+1)]

s可以认为是赋予空列表的值。

foldr以同样的方式工作,只是你从列表的后面而不是从前面开始。

于 2011-05-11T11:27:27.887 回答