我回到OCaml编码,我错过了很多。我错过了这么多,我完全失去了这种语言的推理,今天我就碰壁了。
我想要做的是在一组n个列表之间组合元素。 我首先尝试在两个任意大小的列表之间组合元素来分解问题。
假设我们必须列出:-
和l1 = [1;2;3]
。
我想要做的是获得以下列表:
l2 = [10,20]
我知道如何使用循环结构来做到这一点,但我真的想在没有它们的情况下解决这个问题。
我尝试了以下内容:
l_res = [10;20;20;40;30;60]
但这似乎不起作用。我得到的类型是 let f l1 l2 =
List.map (fun y -> (List.map (fun x -> x * y) l1) l2
,但我想要f : int list -> int list -> int list list
我尝试了许多不同的方法,我觉得我过度复杂。
我错过了什么?
答案 0 :(得分:4)
你遗失的是List.map f [a; b; c]
给出了[f a; f b; f c]
所以你从函数中得到的将是
f [a; b; c] [d; e] = [[ad; ae]; [bd; be]; [cd; ce]]
但你想要
f [a; b; c] [d; e] = [ad; ae; bd; be; cd; ce]
所以你需要使用另一个迭代器,即:
let f l1 l2 =
let res = List.fold_left (fun acc x ->
List.fold_left (fun acc y -> (x * y) :: acc) acc l2
) [] l1 in
List.rev res
或展平你的结果:
val concat : 'a list list -> 'a list
连接列表列表。论证的要素都是 连接在一起(以相同的顺序)给出结果。不 tail-recursive(参数的长度+最长的长度 子列表)。
val flatten : 'a list list -> 'a list
与concat相同。不是尾递归(参数的长度+长度) 最长的子列表。)
答案 1 :(得分:2)
一些Core - 风味的答案:
open Core.Std
let f1 l1 l2 =
List.map (List.cartesian_product l1 l2) ~f:(fun (x, y) -> x * y)
let f2 l1 l2 =
List.concat_map l1 ~f:(fun x -> List.map l2 ~f:(fun y -> x * y))
let f4 l1 l2 =
let open List.Monad_infix in
l1 >>= fun x ->
l2 >>| fun y ->
x * y
显式的最后一个答案(可以说是隐含的另外两个答案)使用了列表monad,这是一个教科书用例。我在电池中找不到列表monad,这可能不是那么令人惊讶,因为它比选项或结果monad更少使用。
答案 2 :(得分:1)
let f l1 l2 =
let multiply x = List.map (( * )x) l2 in
l1 |> List.map multiply
|> List.concat