在SML中查找列表中的max元素

时间:2012-11-14 02:21:18

标签: list sml fold

我试图使用标准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; 这只是我需要定义的另一个函数的一部分,但我正在努力解决折叠部分。

1 个答案:

答案 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;