如何在 ocaml 中一次遍历两个列表?

How to iterate over two lists at once in ocaml?

假设我有以下两个列表: 让 a = [1;2;3;4];; 让 b = [1;3;5;7];; 我想要第三个列表,其中包含 a 和 b 的索引总和; IE 让 c = [2;5;8;11];;

问题是我如何仅使用 List.fold_right、List.fold_left and/or List.map 中的函数来执行此操作? (这是一道作业题,所以我不允许使用递归函数或@。)

map2 函数执行此操作:

let c = List.map2 (fun i j -> i+j) a b;;

既然是作业题,实在只能提示一下了。

假设您想使用 List.mapList.map 的类型是 ('a -> 'b) -> 'a list -> 'b list。换句话说,它适用于一个列表。如果你想用它来解决你的问题,你必须找到你自己的方法将你的两个列表组合成一个列表。您不能使用 List.map 来执行此操作,并且无论您对列表进行什么操作,都可能会为您执行添加操作。所以这看起来不太乐观。

现在假设您想使用 List.fold_leftList.fold_left的类型是('a -> 'b -> 'a) -> 'a -> 'b list -> 'a。折叠的伟大之处在于它允许您携带 'a 类型的任意累积状态。它允许您在处理列表时对该累积状态执行任意修改。

在我看来,您可以将其中一个列表视为此累积状态的一部分,因为您可以折叠处理另一个列表。

(* 与 fold_left 和 @ *)

let (_,c)=
  List.fold_left( fun (iPos,la) ia ->
    (iPos+1,la@[ia+List.nth b iPos]) 
  ) (0,[]) a ;;

(* 有 fold_left 没有 @ 但 rev *)

let (_,c)=
  List.fold_left( fun (iPos,la) ia ->
    (iPos-1,ia+List.nth b iPos::la) 
  ) (List.length b-1,[]) (List.rev a);;

(* 有 fold_left 没有 @ *)

let (_,c)=
  List.fold_left( fun (iPos,la) _ ->
    (iPos-1,List.nth a iPos+List.nth b iPos::la)  
  ) (List.length b-1,[]) a

(* 与 fold_right *)

let (_,c)=
  List.fold_right( fun ia (iPos,la) ->
    (iPos-1,ia+List.nth b iPos::la) 
  ) a (List.length b-1,[])  ;;

(* 附地图 *)

let c=
  let riPos=ref (-1) in
  List.map ( fun ia ->
    riPos := !riPos+1;
    ia+List.nth b !riPos
  ) a ;;

(* 使用 mapi *)

let c=
  List.mapi ( fun iPos ia ->
    ia+List.nth b iPos
  ) a ;;

(* 使用 map2 *)

let c=List.map2 (+) a b;;