函数返回'列表而不是'列表

时间:2018-01-10 09:54:22

标签: functional-programming ocaml caml-light

以下代码尝试创建一个给定列表列表的函数'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.

我真的很难弄清楚错误究竟在哪里。

2 个答案:

答案 0 :(得分:2)

您可以执行以下操作:

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

其中llistlist的{​​{1}}。

例如:

list

提示:使用fold_left,fold_right,map等时...如果您对自己提供的功能不满意,请创建一个真实的命名函数(即使用first_element_lists [[11; 12; 13]; [21; 22; 23]; [31; 32; 33]];; - : int list = [11; 21; 31] ),这样您就可以验证它有你想要的类型。

答案 1 :(得分:2)

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

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将一个函数应用于列表的每个元素,并返回包含所有结果的列表。
  • List.hd是一个返回列表第一个元素(称为 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

您可以通过多种方式解决此问题,其中一种方式是Bromind's great answer