您不会引用错误消息或说出您正在使用哪个编译器。这是我从 SML/NJ 得到的:
3867615/john316.sml:7.25-7.64 Error: operator and operand don't agree [tycon mismatch]
operator domain: int list
operand: int
in expression:
answer x
3867615/john316.sml:7.25-7.64 Error: operator and operand don't agree [circularity]
operator domain: 'Z * 'Z list
operand: 'Z * 'Z
in expression:
(findAll f) l :: (findAll f) r
3867615/john316.sml:7.25-7.64 Error: argument of raise is not an exception [tycon mismatch]
raised: _ list
in expression:
raise (answer x :: (findAll <exp>) l :: (findAll <exp>) r)
3867615/john316.sml:9.9-9.37 Error: operator and operand don't agree [circularity]
operator domain: 'Z * 'Z list
operand: 'Z * 'Z
in expression:
(findAll f) l :: (findAll f) r
第一个错误应该相当清楚:answer
被声明为期望一个int list
参数,但answer x
使用x
来自 aNode
并且必须是 a 的 an int
。第三个错误可能是优先级问题:您可以看到编译器如何解析您的表达式,这可能不是您想要的。(但你的意图没有意义,我将在下面解释。)
第二个和第四个错误是由于您混淆了::
(“cons”) 构造函数,该构造函数在列表的前面添加一个元素,而@
(“append”) 运算符则连接两个列表。
现在我回到answer
例外。它是干什么用的?您的函数必须找到所有出现的事件,因此它必须遍历整个树。没有任何情况需要您提前返回。因此,您不需要例外。您基本上已经得到了正确的算法(在空树中,没有匹配项,因此返回空列表;在节点中,将匹配项添加到递归调用的结果(如果存在)),只是不要使事情复杂化。
进行两次更正,我们得到以下代码(编译):
fun findAll f Empty = []
| findAll f (Node(x, l, r)) =
if f x then x :: findAll f l @ findAll f r
else findAll f l @ findAll f r