以下代码尝试创建一个给定列表列表的函数'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.
我真的很难弄清楚错误究竟在哪里。
答案 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
其中llist
是list
的{{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。