我有一个关于函数式编程的大学课程,我使用SML。作为考试的准备,我正在研究一些没有解决方案的旧考试。
我遇到问题的唯一问题之一是使用foldl
的以下问题:
考虑程序骨架:好玩 addGt k xs = List.foldl(...)... xs; 填写两个缺失的部分 (由点代表......),所以 addGt k xs是这些的总和 xs中的元素,大于 ķ。例如,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;
我真的很感激这个问题的一些帮助,也许是一个非常简短的评论,可以对foldl
和foldr
函数有所了解!
非常感谢。
答案 0 :(得分:8)
我刚才的解决方案如下:
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
是一个curried函数,它将第一个参数作为('a * 'b -> 'b)
类型的另一个函数。您使用了类型为(fn x => if x > k then op+ else 0)
的{{1}}。您应该为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
答案 1 :(得分: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
- 值视为一种累加器,也就是说,ai
是结果,如果列表只是[x1, x2, ..., xi]
{1}}(或者更确切地说,列表的前i个元素)。
您的功能通常采用以下形式:
fn (x, a) => ...
您需要做的是思考:好的,如果我有列表中的下一个元素x(i+1)
和值ai
,这是列表{{1}的结果},我需要做些什么才能找到值[x1, x2, ..., xi]
,这是列表a(i+1)
的结果。
[x1, x2, ..., xi, x(i+1)]
可以被认为是空列表的值。
s
的工作方式相同,只是从列表的后面而不是从前面开始。