0

以下代码尝试创建一个函数,该函数'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.

我真的很难弄清楚错误到底在哪里。

4

2 回答 2

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的在哪里list

例如 :

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

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

于 2018-01-10T10:11:06.157 回答
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 的最佳答案

于 2018-01-10T16:25:32.910 回答