0

这是家庭作业的一部分,所以我的目标是了解为什么这是错误的。正如我之前提到的,我使用的是莫斯科 ML。

fun filter pred = let
 fun f ([], a) = []
 | f ([], a) = a
 |   f (e::L, a) = if pred e then (f L (e::a) ) else (f L a)

in
 f
end

我得到的错误是:

| f (e::L, a) = if pred e then (f L (e::a) ) else (f L a)
                                  ^
Type clash: expression of type 
'a list cannot have type
'a list * 'b list

我一直在阅读文档,但确实没有帮助。我真正不明白的是'b list 的来源。在我们的任务中,我们必须使用带有尾递归的累加器。我相信我的错误在于过滤器如何调用函数 f。Filter 将谓词作为参数, f 应采用列表和累加器,后者最初是空列表。

我试过像这样调用 f:f L [],但在其他示例中,我们实际上不必用它的参数调用 f,它以某种方式自动传递。

无论如何,任何帮助理解我的错误在哪里以及如何解决问题的指导将不胜感激。

-艾蒂

(如果有人可以给我任何关于解码类型表达式错误的提示,这也可能非常有益。)

4

2 回答 2

1

您混淆了元组与咖喱函数调用。您的定义f需要一个元组 (a,b),但您将其参数传递为f a b. 尝试用替换你的递归f L ...调用f (L,...)

类型错误有点无用,但它基本上是说当它需要一个 2 元组列表时你正在传递一个列表。

于 2010-10-24T22:01:27.087 回答
1

(f L (e::a))仅当f是类型为 的柯里化函数时才有效'a list -> 'a list -> 'a list。你应该这样做:

if pred e then (f (L, (e::a))) else (f (L,a))

顺便说一句,SMLNJ 抱怨冗余匹配(f ([], a)给出了两个子句)。

于 2010-10-24T22:01:30.383 回答