最后使用 ML 实现

Implement last using ML

我正在尝试在 ML 中实施 last。 last 可以 return 列表的最后一个元素。

例如,L=[1, 2, 3, 4],last(L) = 4。这是我的实现。

fun last [] = last((h::nil)) = h | last((h::tail)) = last(tail);

它给我"unbound variable or constructor: h"。我理解的h是我声明的变量,代表链表的头部,为什么变量h会报错?

你的定义可以布局为

fun last [] = last((h::nil)) = h 
| last((h::tail)) = last(tail);

SML 将第一个子句解释为尝试将比较结果 last((h::nil)) = h 的布尔值分配给 last []。由于您在该子句中匹配的模式是 [] 并且 [] 不涉及 h,因此比较 last((h::nil)) = h 中的 h 是未绑定的,因此错误。无论如何,这样的比较意义不大,显然不是您的意图。

请注意 last [] 无法合理定义。您的选择是要么简单地忽略它,要么通过引发错误(Empty 或自定义错误)来解决它。函数 last 的真正基础子句是 1 元素列表的基础子句。你似乎知道如何处理它。当您停止尝试使用第一个子句同时为 last []last (h::nil) 赋值而只是执行后者时,您的代码实际上有效:

fun last (h::nil) = h 
| last (h::tail) = last tail;

这里我去掉了h::nilh::tailtail周围的3对多余的括号。在 SML 中,函数调用不需要括号。只有在需要确保正确分组时才需要括号。请注意,第一个模式也可以更简洁地写为 [h].

由于您没有给出 last [] 的定义,因此您收到非详尽匹配警告。您可以忽略该警告(因为它在仅为非空列表定义的函数中很常见),或者将其写为

fun last [] = raise Empty
|   last (h::nil) = h 
|   last (h::tail) = last tail;