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来实现