函数返回 'a list list 而不是 'a list

function returning 'a list list instead of 'a list

以下代码尝试创建一个函数 'a list list -> 'a list,该函数给定一个列表列表,返回一个由从列表中取出的每个第一个元素组成的列表。

#let first_element_lists lis =
 let f x y =
    match y with
    [] -> x
    |[]::[] -> x
    |[z]::[zs] -> match [z] with
        [] -> x
        | v::vs -> v::x
in
foldr f [] lis;;


Toplevel input:
>   foldr f [] lis;;
>         ^
This expression has type 'a list -> 'a list list -> 'a list,
but is used with type 'a list -> 'a list list -> 'a list list.

我真的很难找出错误所在。

您可以执行以下操作:

let extract_and_append accumulator element =
match element with
| [] -> accumulator
| hd::_ -> accumulator @ [hd]

此函数处理列表并将第二个元素的第一个元素附加到第一个元素的末尾。

有了它,你可以使用 fold_left(提示:如果可以,请始终使用 fold_left,它是尾递归的):

let first_element_lists llist = 
List.fold_left extract_and_append [] llist

其中 llist 是您 listlist

例如:

first_element_lists [[11; 12; 13]; [21; 22; 23]; [31; 32; 33]];;
- : int list = [11; 21; 31]

提示:当使用 fold_left、fold_right、map 等时...如果您对所提供的函数没有信心,请创建一个真正命名的函数(即使用 let ... in), 所以你可以验证它是否有你想要的类型。

另一种方法,完全依赖于标准库:

let firsts l = List.map List.hd l

查看实际效果:

firsts [[1;2;3];[4;5;6];[7;8;9]];;
- : int list = [1; 4; 7]
  • List.map 将一个函数应用到列表的每个元素和列表的 returns 以及所有结果。
  • List.hd 是 returns 列表的第一个元素(称为 head)的函数。

如评论中所述,当其中一个列表为空时,此操作失败。

firsts [[1;2;3]; []];;

Exception: (Failure hd).
Raised at file "pervasives.ml", line 32, characters 22-33
Called from file "list.ml", line 67, characters 20-23
Called from file "list.ml", line 67, characters 32-39
Called from file "toplevel/toploop.ml", line 180, characters 17-56

您可以通过多种方式解决此问题,其中之一是