此表达式具有类型 'a 列表选项,但表达式应为类型 'b 列表

This expression has type 'a list option but an expression was expected of type 'b list

我正在用 ocaml 编写一个函数,它 return 是列表中最长的列表,使用类型选项并使用 List.fold_right

let longest( lst : 'a list list) : 'a list option = 
  List.fold_right( fun (i : 'a list)  (y : 'a list option) -> if List.length i > List.length y then (Some i) y else y) lst None 

但是我一直收到这个错误

This expression has type 'a list option
but an expression was expected of type 'b list

函数应该return一些后跟最长的列表或者none如果它是空的

让我们让它更容易消化。

let longest (lst : 'a list list) (x : 'a list option) = 
  List.fold_right 
    (fun (i : 'a list)  (y : 'a list option) -> 
       if List.length i > List.length y then (Some i) y 
       else y) 
    lst 
    None 

此投诉的具体问题与:

List.length y

在这种情况下,y 应该是 'a list option 类型,但 List.length 需要 'a list.

类型的值

您需要在传递给 List.fold_right 的函数中做一些 pattern-matching 以确定初始值(在您的代码中容易混淆地表示为 y)是否为 NoneSome ... 然后相应地处理它。

它可能看起来像下面这样。请注意,您使用的类型注释是无关紧要的,因为 OCaml 会推断类型。

let longest lst =
  List.(
    let f x i =
      match i with 
      | None                                  -> ...
      | Some lst' when length x > length lst' -> ...
      | _                                     -> ...
    in
    fold_right f lst None
  )

将 [] 作为特殊情况处理,删除未使用的 x 参数并减少每个列表调用一次 List.length 的次数我得到这个:

let longest lst =
  match lst with   
   | [] -> None   
   | x :: xs -> 
      Some (fst (List.fold_right
        (fun i ((y, ly) as p) ->
          let li = List.length i
          in
            if li > ly
            then (i, li)
            else p)
        xs
        (x, List.length x)));;

val longest : 'a list list -> 'a list option = <fun>
# longest [];;
- : 'a list option = None
# longest [[1]; [1;2;3]; [1;2]];;
- : int list option = Some [1; 2; 3]