List 为什么不是';这不是一张单子吗?
请原谅我对OCaml的陌生,但我有一个非常简单的函数,其中我返回两个列表的交集,但只有当元素同时位于两个列表中时才返回。在第三行,我被告知“此表达式的类型为'a,但表达式的类型应为'a list',但这不是我正在输出的列表吗List 为什么不是';这不是一张单子吗?,list,recursion,pattern-matching,ocaml,typeerror,List,Recursion,Pattern Matching,Ocaml,Typeerror,请原谅我对OCaml的陌生,但我有一个非常简单的函数,其中我返回两个列表的交集,但只有当元素同时位于两个列表中时才返回。在第三行,我被告知“此表达式的类型为'a,但表达式的类型应为'a list',但这不是我正在输出的列表吗 let rec intersection (l1 : 'a list) (l2 : 'a list) : 'a list = match l1,l2 with | [],[] -> [] (* empty lists *) | [h1
let rec intersection (l1 : 'a list) (l2 : 'a list) : 'a list = match l1,l2 with
| [],[] -> [] (* empty lists *)
| [h1::t1], [h2::t2] -> (* non-empty lists *)
if h1 = h2 (* if both elements are the same *)
then h1 :: intersection(t1,t2) (* include in intersection response *)
else intersection(t1, t2) (* else ignore it and check the remaining elements *)
表达式
a::b
是一个列表,其头部为a
,尾部为b
。那么表达式[a::b]
就是一个列表列表。很可能您的模式应该是h1::t1
和h2::t2
如果你像@PieOhPah所指出的那样发布整个函数,那么帮助就会容易得多
更新
您的代码中至少有两个错误。如果我按照上面给出的方式编译代码,我会看到:
File "a1.ml", line 5, characters 13-15:
Error: This expression has type 'a but an expression was expected of type
'a list
The type variable 'a occurs inside 'a list
File "a2.ml", line 5, characters 31-38:
Error: This expression has type 'b * 'c
but an expression was expected of type 'a list
如果我将您的模式从[h1::t1],[h2::t2]
更改为h1::t1,h2::t2
,我会看到:
File "a1.ml", line 5, characters 13-15:
Error: This expression has type 'a but an expression was expected of type
'a list
The type variable 'a occurs inside 'a list
File "a2.ml", line 5, characters 31-38:
Error: This expression has type 'b * 'c
but an expression was expected of type 'a list
发生第二个错误的原因是,对交叉点的递归调用传递的是元组交叉点(a,b)
。但是,交叉点
是以货币形式定义的,即它采用单独的参数交叉点a b
。这就是@PieOhPah所指出的
如果我同时做了这两个更改,我就看不到任何进一步的类型错误。还有其他错误,但它们不是类型错误。所有ARM必须返回相同的类型。在else
表达式中,在我看来交叉点(t1,t2)
只能返回一个'a
。发布整个函数会更有帮助。intersection(t1,t2)
使用元组(t1,t2)
调用intersection
。它应该被称为交叉点t1 t2
。似乎没有改变任何类型错误。仍然获取此表达式的类型为“a”,但表达式应为“a列表”类型。类型变量“a出现在”列表中。如果我按照建议更改模式,则不会得到相同的错误。有一个错误,但不是同一个错误。事实上,这是上面@PieOhPah指出的错误。添加了整个函数。OCaml不允许在没有列表列表的情况下在括号内定义列表吗?列表有两种表示法:[a;b]
和a::b::[]
。您已经组合了这些符号,所以您得到了一个列表。@JeffreyScofield的答案很清楚。cons(:
)已经构建了一个列表。这意味着您应该匹配(h1::t1,h2::t2)
,而不使用方括号(括号仅用于澄清)。这不会改变任何东西。无论我如何设置列表格式,第5行的h1仍然会出现完全相同的类型错误。是的,如果您进行@PieOhPah和我建议的更改,则会出现不同的错误。请参阅PieOhPah对您原始帖子的评论。