2

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

4

1 回答 1

3

fold函数的定义中,您要求函数f必须以咖喱形式接受它的参数,即:f 1 1 而不是f(1,1).

据我了解,那么您对fold函数的定义是正确的。因此,您需要对函数中的匿名函数进行适当的更改max

在 SML 中,柯里化实际上只是语法糖。例如:

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 ,那么您应该对这种情况进行模式匹配。这也修复了关于“匹配非详尽”的警告,并且是正确的地方。

fun max [] =  0
  | max (x::xs) = fold (fn a => fn b => if a > b then a else b) (x::xs) x;
于 2012-11-14T10:29:00.220 回答