2017-10-19 179 views
0

我在OCaml的一个函数,它应该合并两个列表:这个表达键入“列表,但预计类型的表达式”一

let rec merge (list1, list2) = 
    match (list1, list2) with 
     ([], []) -> merge (List.tl list1, List.tl list2) :: List.hd list1 :: List.hd list2 
     |(_, []) -> merge (List.tl list1, list2) :: List.hd list1 
     |([], _) -> merge (list1, List.tl list2) :: List.hd list2;; 

但由于某些原因,编译器不会让这样的代码通过退出:

Error: This expression has type 'a list but an expression was expected of type 'a The type variable 'a occurs inside 'a list

我该如何指定这些列表'我试图通过,而不是'一个?

回答

2

首先,这个功能不起作用。如果两个列表为空,则合并尾部并连接它们中的每一个的头部,但是...呃...它们是空的...

无论如何,您的问题是您使用的是::运算符串联),其类型为'a -> 'a list -> 'a list,所以左边的成员应该是一个元素,右边的是列表,左边的是列表,右边是元素,所以它不能工作。

关于你的问题,因为类型推断,你不能告诉你是对的编译器,他是错的,在这种情况下,错误是真正明确:

List.tl l (* 'a list *) :: List.hd l (* 'a *) 

将始终返回错误,因为你有一个无限的类型(因为::'a -> 'a list -> 'a list型的,我让你尝试确定一个有限型'a,可以搭配您的串联)

所以,我想你想做的事是这样的:

let rec merge (list1, list2) = 
    match list1, list2 with 
     | [], _ -> list2;; 
     | hd :: tl, _ -> hd :: merge tl list2 
相关问题