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

请原谅我对OCaml的陌生,但我有一个非常简单的函数,其中我返回两个列表的交集,但只有当元素同时位于两个列表中时才返回。在第三行,我被告知“此表达式的类型为'a,但表达式的类型应为'a list',但这不是我正在输出的列表吗

 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对您原始帖子的评论。