如何在ocaml中一次迭代两个列表?

时间:2015-10-01 14:39:07

标签: list functional-programming ocaml fold

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

问题是如何仅使用List.fold_right,List.fold_left和/或List.map中的函数来执行此操作? (这是一个家庭作业问题,因此我不允许使用递归函数或@。)

3 个答案:

答案 0 :(得分:5)

由于这是一个家庭作业问题,我们实际上只能给出提示。

我们假设你想使用List.mapList.map的类型为('a -> 'b) -> 'a list -> 'b list。换句话说,它在一个列表上工作。如果您想用它来解决问题,您必须找到自己的方法将两个列表合并到一个列表中。您无法使用List.map来执行此操作,无论您如何组合列表,都可以为您添加。所以这看起来并不乐观。

现在让我们说你想使用List.fold_leftList.fold_left的类型为('a -> 'b -> 'a) -> 'a -> 'b list -> 'a。折叠的好处在于它允许您携带'a类型的任意累积状态。并且它允许您在处理列表时对此累积状态执行任意修改。

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

答案 1 :(得分:3)

map2函数执行此操作:

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

答案 2 :(得分:1)

(* with fold_left and @ *)

List<Object>

(* with fold_left and without @ but rev *)

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

(* with fold_left and without @ *)

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

(* with fold_right *)

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

(* with map *)

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

(* with mapi *)

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

(* with map2 *)

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