gcd, map for ocaml

gcd 的代码如下

let gcd a b =
  let rec gcd_int x y =
    let r = x mod y in
    if r = 0 then y
    else gcd_int y r
  in
  if b = 0 then a
  else gcd_int a b ;;

map的简单实现为

let rec map f =
   [] -> []
  |h::l -> f h :: map f l ;;

 这个实现不是尾递归的,对于长表来说可能会栈溢出,尾递归的版本为

let map f l =
  let reverse lst r =
    match lst with
        [] -> r
       | h::rest -> reverse rest (h::r)
  in
  let rec map_int f l  r=
    match f with
       [] -> r
      | h::rest -> map_int f rest ((f h)::r)
  in
  reverse (map_int f l []) [] ;;

 仔细观察了一下reverse的代码,其实跟map_int的代码很像,其实是map_int里面函数为identity的特例,于是map可以重新实现为

1 let map f l =
2     let rec map_int g ll rr =
3       match ll with
4       | [] -> rr
5       | h::r -> map_int g r ( (g h) :: rr )
6     in
7     map_int (fun i -> i) (map_int f l []) [] ;;

这样reverse的过程通过map_int来实现

posted on 2012-11-25 11:03  mathlover  阅读(225)  评论(0编辑  收藏  举报

导航