OCaml 是一种函数式语言,因此我们想尝试将过程分解为尽可能多的函数式部分。
第 1 步是“列出事物并产生所有组合”。我们不在乎之后会发生什么;我们只想知道所有这些组合。如果您希望每个组合只出现一次(即在您的示例中,(a, b) 会出现,但 (b, a) 不会出现),那么一个简单的递归定义就足够了。
let rec ordered_pairs xs =
match xs with
| [] -> []
| (x :: xs) -> List.append (List.map (fun y -> (x, y)) xs) (ordered_pairs xs)
如果您想要反向重复((a, b) 和 (b, a)),那么我们可以在最后添加它们。
let swap (x, y) = (y, x)
let all_ordered_pairs xs =
let p = ordered_pairs xs in
List.append p (List.map swap p)
现在我们有了所有元组的列表。接下来会发生什么取决于你想要什么样的结果。您很可能正在查看内置 List module 中的某些内容。如果您想将该函数应用于每一对以产生副作用,List.iter 就可以了。如果您想将结果累积到一个新列表中,List.map 会这样做。如果您想应用一些操作来组合结果(例如,每个函数返回一个数字并且您想要数字的总和),那么 List.map 后跟 List.fold_left(或复合 List.fold_left_map)就可以了。
当然,如果您刚刚开始,自己编写这些List 函数会很有启发性。它们中的每一个都是简单的一两行递归定义,对自己编写很有指导意义。