我试图使用标准ML找到列表中的最大值。我需要使用给定的折叠函数:
fun fold f [] base = base
| fold f (x::xs) base = fold f xs (f x base);
这是我到目前为止所拥有的:
fun max (x::xs) = fold (fn (a, b) => if a > b then a else 0) x (x::xs);
我有0,因为如果列表为空,那么我需要返回0; 这只是我需要定义的另一个函数的一部分,但我正在努力解决折叠部分。
答案 0 :(得分:3)
在您对fold
函数的定义中,您要求函数f
必须以咖喱形式获取其参数,即:f 1 1
而不是f(1,1)
。< / p>
据我了解,那么你对fold
函数的定义是正确的。因此,您需要对max
函数中的匿名函数进行适当的更改。
在SML中,currying实际上只是语法糖。例如:
fun foo a b = a+b
最终会成为(在去世后):
val rec foo = fn a => fn b => a+b
还可以看出这两个函数具有相同的类型:
- fun foo a b = a+b;
val foo = fn : int -> int -> int
- val rec foo = fn a => fn b => a+b;
val foo = fn : int -> int -> int
因此,匿名函数必须在相同的行上进行定义。
此外,您已将参数混合到fold
。在max
函数的最后一部分中,您将以相反的顺序给出最后两个参数。
最后一个问题是你的匿名函数返回0.这会使你的匿名函数不变,并在某些情况下使其失败。例如:
max [1,4,65,7,6];
试着找出自己的原因。
如果你真的需要在max
的输入列表为空时返回0,那么你应该模式匹配这种情况。这也修复了关于“match nonexhaustive”的警告,并且是正确的做法。
fun max [] = 0
| max (x::xs) = fold (fn a => fn b => if a > b then a else b) (x::xs) x;