假设我有以下两个列表: 设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中的函数来执行此操作? (这是一个家庭作业问题,因此我不允许使用递归函数或@。)
答案 0 :(得分:5)
由于这是一个家庭作业问题,我们实际上只能给出提示。
我们假设你想使用List.map
。 List.map
的类型为('a -> 'b) -> 'a list -> 'b list
。换句话说,它在一个列表上工作。如果您想用它来解决问题,您必须找到自己的方法将两个列表合并到一个列表中。您无法使用List.map
来执行此操作,无论您如何组合列表,都可以为您添加。所以这看起来并不乐观。
现在让我们说你想使用List.fold_left
。 List.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 ;;