首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OCaml: fold_left,fold_right转换

OCaml: fold_left,fold_right转换
EN

Stack Overflow用户
提问于 2014-05-02 08:33:11
回答 1查看 655关注 0票数 1

http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html中,我们有:

val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a

List.fold_left f a [b1; ...; bn] is f (... (f (f a b1) b2) ...) bn

val fold_right : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b

List.fold_right f [a1; ...; an] b is f a1 (f a2 (... (f an b) ...))。不是尾递归的。

问题是如何使用fold_left函数实现“List.fold_right”函数。这就是我在网上找到的答案:

代码语言:javascript
复制
let rec my_fold_left f a l = List.fold_right (fun x g a -> g (f a x)) l (fun x -> x) a;;

val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a

我第一次写到:

代码语言:javascript
复制
let rec my_fold_left_old f a l = List.fold_right (fun x a -> f a x) l a;;

val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a

类型检查是正确的,但是my_fold_left_old是错误的,因为它将列表从最后一个元素扫描到第一个元素。

有人能解释上面的函数my_fold_left,List.fold_right只能有3个参数,但是上面的my_fold_left有4个参数吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-02 09:51:43

它在奔跑。从本质上说,List.fold_right有一种('a -> 'b -> 'b) -> 'a list -> 'b类型,这个定义将该操作与'b的函数类型一起使用。

如果您用'c -> 'd代替'b,跳过冗余的parens,您可以看到这如何为'b生成“四个参数”:

代码语言:javascript
复制
('a -> 'c -> 'd -> ('c -> 'd)) -> 'a list -> 'c -> 'd

因此,List.fold_right折叠在列表上,生成一个函数,该函数被应用于一个参数以生成最终结果。为了更清楚地说明这一点,让我们用一个命名的临时代码重写它:

代码语言:javascript
复制
 let foldl f init list =
  let fold_result =
    List.fold_right
      (fun elt g acc -> g (f acc elt))
      list
      (fun x -> x) in
  fold_result init
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23423943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档