List OCaml函数帮助,涉及解析列表列表

List OCaml函数帮助,涉及解析列表列表,list,ocaml,List,Ocaml,我正在尝试创建一个OCaml函数rv,该函数将遍历一个列表列表,并将元素重新组织为另一个列表列表,以便第一个列表由每个原始列表的第一个元素组成,第二个列表由每个列表的第二个元素组成,等等 例如: [[“a”;“b”;“c”];[“d”;“e”;“f”] 我已经有了一个函数gather,它将获取列表列表,并从每个列表中提取某个索引的元素。因此,基本上使用上一个示例,我可以说gather(list,1)并返回[“b”;“e”]。我需要一种方法来遍历List.length次,并对每个元素索引使用聚集

我正在尝试创建一个OCaml函数
rv
,该函数将遍历一个列表列表,并将元素重新组织为另一个列表列表,以便第一个列表由每个原始列表的第一个元素组成,第二个列表由每个列表的第二个元素组成,等等

例如:
[[“a”;“b”;“c”];[“d”;“e”;“f”]

我已经有了一个函数gather,它将获取列表列表,并从每个列表中提取某个索引的元素。因此,基本上使用上一个示例,我可以说
gather(list,1)
并返回
[“b”;“e”]
。我需要一种方法来遍历
List.length
次,并对每个元素索引使用聚集


这给我带来这么多麻烦的原因是应用的限制(是的,这是针对学校的)。我不允许使用循环或局部/全局变量。我也不允许在函数体中使用“let”。是否有其他方法可以递归地为每个元素索引使用
聚集
?我是否应该使用另一个函数递归地使用
聚集
,然后在
rv
中重复使用该函数?如果是这样的话,你会怎么做呢?

要克服循环的限制,请使用递归函数

关于使用
let
的限制有点愚蠢。您可以通过向函数传递参数来解决这个问题,在某种程度上,可以编写
(函数x->e)v
,而不是
让x=v在e
中。但可以将其视为一种暗示,即您应该利用诸如
List.map
List.fold\u left
等函数

一般来说,列表不是数组;它们不能通过元素的索引来访问。当然,你可以这样做,但它既麻烦又低效。访问列表的自然方法是使用模式匹配或
list.hd
list.tl
函数来分割列表的第一个元素和其余部分,或者使用
list.map
等函数遍历整个列表

例如,如果您只需要每个列表的第一个元素,那么您可以使用

List.map List.hd lists
List.map List.tl lists
给出了每个列表的剩余部分。这表明了一种递归方法:结果的开头是
List.map List.hd lists
,结果的结尾是
List.map List.tl lists
的换位

let rec transpose lists =
  List.map List.hd lists :: transpose (List.map List.tl lists)
现在,很明显,我们需要在某个时刻终止。假设所有列表都具有相同的长度,我们需要在列表为空时停止,这可以通过查看第一个列表来测试。我将把这个作为练习

为了理解这段代码的作用,我建议使用
#trace
指令在Ocaml顶级中键入它,并查看几个示例中的操作。为此,如果将
转置
函数设为单态函数,则会有所帮助

# let rec tranpose (lists : string list list) = …;;
val transpose : string list list -> string list list = <fun>
# #trace transpose;;
transpose is now traced.
# transpose [["a"; "b"; "c"]; ["d"; "e"; "f"]];;
transpose <-- [["a"; "b"; "c"]; ["d"; "e"; "f"]]
transpose <-- [["b"; "c"]; ["e"; "f"]]
transpose <-- [["c"]; ["f"]]
transpose <-- [[]; []]
transpose --> []
transpose --> [["c"; "f"]]
transpose --> [["b"; "e"]; ["c"; "f"]]
transpose --> [["a"; "d"]; ["b"; "e"]; ["c"; "f"]]
- : string list list = [["a"; "d"]; ["b"; "e"]; ["c"; "f"]]
#让rec transpose(列表:字符串列表)=…;;
val转置:字符串列表->字符串列表=
##跟踪转置;;
转置现在被追踪。
#转置[“a”;“b”;“c”];[“d”;“e”;“f”];;
转置[“a”;“d”];[“b”;“e”];[“c”;“f”]
-:字符串列表=[“a”;“d”];[“b”;“e”];[“c”;“f”]]

非常感谢。我能够使用您的帮助创建函数。我非常感激@Gilles如果没有递归,你会怎么做?@jonnyd42递归是这里的惯用方法。如果要求您在不使用递归的情况下执行此操作,这可能是使用
左折
右折
的练习@Gilles,这是我即将进行的测试的练习问题。你能给我一些关于如何使用折叠函数的提示吗?