letrec length lst = match lst with | [] -> 0 | _ :: t -> 1 + length t
尾递归:
1 2 3 4 5 6 7
let length lst = letrec aux lst len = match lst with [] -> len |_::t -> aux t (len+1) in aux lst 0;;
列表反转
普通递归:
1 2 3 4
letrec rev lst = match lst with | [] -> [] | h :: t -> (rev t) @ [h]
尾递归:
1 2 3 4 5 6 7
let rev lst = letrec aux lst l = match lst with [] -> l |x::xs -> aux xs (x::l) in aux lst [];;
列表映射
普通递归:
1 2 3 4
letrec map f lst = match lst with | [] -> [] | h :: t -> (f h) :: (map f t)
尾递归:
1 2 3 4 5 6 7
let map f lst = letrec aux f lst l = match lst with []-> List.rev l |x::xs -> aux f xs ((f x)::l) in aux f lst [];;
计算树的和
树的Type定义
1
type tree = | Leaf of int | Node of int * tree * tree
普通递归:
1 2 3
letrec sum_tree t = match t with | Leaf n -> n | Node(n, left, right) -> n + sum_tree left + sum_tree right
尾递归:
1 2 3 4 5 6 7 8
let sum_tree t = letrec aux s l = match l with [] -> s |Leaf n :: xs -> aux (s+n) xs |Node(n,left,right)::xs -> aux (s+n) (left::right::xs) in aux 0 [t];;
# #show List;; moduleList : sig type'a t = 'alist = [] | (::) of'a * 'alist val length : 'a t -> int val compare_lengths : 'a t -> 'b t -> int val compare_length_with : 'a t -> int -> int val cons : 'a -> 'a t -> 'a t val hd : 'a t -> 'a val tl : 'a t -> 'a t val nth : 'a t -> int -> 'a val nth_opt : 'a t -> int -> 'a option val rev : 'a t -> 'a t val init : int -> (int -> 'a) -> 'a t val append : 'a t -> 'a t -> 'a t val rev_append : 'a t -> 'a t -> 'a t val concat : 'a t t -> 'a t val flatten : 'a t t -> 'a t val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int val iter : ('a -> unit) -> 'a t -> unit val iteri : (int -> 'a -> unit) -> 'a t -> unit val map : ('a -> 'b) -> 'a t -> 'b t val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t val rev_map : ('a -> 'b) -> 'a t -> 'b t val filter_map : ('a -> 'b option) -> 'a t -> 'b t val concat_map : ('a -> 'b t) -> 'a t -> 'b t val fold_left_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b t -> 'a * 'c t val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a val fold_right : ('a -> 'b -> 'b) -> 'a t -> 'b -> 'b val iter2 : ('a -> 'b -> unit) -> 'a t -> 'b t -> unit val map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t val rev_map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t val fold_left2 : ('a -> 'b -> 'c -> 'a) -> 'a -> 'b t -> 'c t -> 'a val fold_right2 : ('a -> 'b -> 'c -> 'c) -> 'a t -> 'b t -> 'c -> 'c val for_all : ('a -> bool) -> 'a t -> bool val exists : ('a -> bool) -> 'a t -> bool val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool val mem : 'a -> 'a t -> bool val memq : 'a -> 'a t -> bool val find : ('a -> bool) -> 'a t -> 'a val find_opt : ('a -> bool) -> 'a t -> 'a option val find_map : ('a -> 'b option) -> 'a t -> 'b option val filter : ('a -> bool) -> 'a t -> 'a t val find_all : ('a -> bool) -> 'a t -> 'a t val filteri : (int -> 'a -> bool) -> 'a t -> 'a t val partition : ('a -> bool) -> 'a t -> 'a t * 'a t val partition_map : ('a -> ('b, 'c) Either.t) -> 'a t -> 'b t * 'c t val assoc : 'a -> ('a * 'b) t -> 'b val assoc_opt : 'a -> ('a * 'b) t -> 'b option val assq : 'a -> ('a * 'b) t -> 'b val assq_opt : 'a -> ('a * 'b) t -> 'b option val mem_assoc : 'a -> ('a * 'b) t -> bool val mem_assq : 'a -> ('a * 'b) t -> bool val remove_assoc : 'a -> ('a * 'b) t -> ('a * 'b) t val remove_assq : 'a -> ('a * 'b) t -> ('a * 'b) t val split : ('a * 'b) t -> 'a t * 'b t val combine : 'a t -> 'b t -> ('a * 'b) t val sort : ('a -> 'a -> int) -> 'a t -> 'a t val stable_sort : ('a -> 'a -> int) -> 'a t -> 'a t val fast_sort : ('a -> 'a -> int) -> 'a t -> 'a t val sort_uniq : ('a -> 'a -> int) -> 'a t -> 'a t val merge : ('a -> 'a -> int) -> 'a t -> 'a t -> 'a t val to_seq : 'a t -> 'aSeq.t val of_seq : 'aSeq.t -> 'a t end
utop # #show List;; moduleList : sig type'a t = 'alist = [] | (::) of'a * 'alist val length : 'a t -> int val compare_lengths : 'a t -> 'b t -> int val compare_length_with : 'a t -> int -> int val is_empty : 'a t -> bool val cons : 'a -> 'a t -> 'a t val hd : 'a t -> 'a val tl : 'a t -> 'a t val nth : 'a t -> int -> 'a val nth_opt : 'a t -> int -> 'a option val rev : 'a t -> 'a t val init : int -> (int -> 'a) -> 'a t val append : 'a t -> 'a t -> 'a t val rev_append : 'a t -> 'a t -> 'a t val concat : 'a t t -> 'a t val flatten : 'a t t -> 'a t val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int val iter : ('a -> unit) -> 'a t -> unit val iteri : (int -> 'a -> unit) -> 'a t -> unit val map : ('a -> 'b) -> 'a t -> 'b t val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t val rev_map : ('a -> 'b) -> 'a t -> 'b t val filter_map : ('a -> 'b option) -> 'a t -> 'b t val concat_map : ('a -> 'b t) -> 'a t -> 'b t val fold_left_map : ('acc -> 'a -> 'acc * 'b) -> 'acc -> 'a t -> 'acc * 'b t val fold_left : ('acc -> 'a -> 'acc) -> 'acc -> 'a t -> 'acc val fold_right : ('a -> 'acc -> 'acc) -> 'a t -> 'acc -> 'acc val iter2 : ('a -> 'b -> unit) -> 'a t -> 'b t -> unit val map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t val rev_map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t val fold_left2 : ('acc -> 'a -> 'b -> 'acc) -> 'acc -> 'a t -> 'b t -> 'acc val fold_right2 : ('a -> 'b -> 'acc -> 'acc) -> 'a t -> 'b t -> 'acc -> 'acc val for_all : ('a -> bool) -> 'a t -> bool val exists : ('a -> bool) -> 'a t -> bool val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool val mem : 'a -> 'a t -> bool val memq : 'a -> 'a t -> bool val find : ('a -> bool) -> 'a t -> 'a val find_opt : ('a -> bool) -> 'a t -> 'a option val find_index : ('a -> bool) -> 'a t -> int option val find_map : ('a -> 'b option) -> 'a t -> 'b option val find_mapi : (int -> 'a -> 'b option) -> 'a t -> 'b option val filter : ('a -> bool) -> 'a t -> 'a t val find_all : ('a -> bool) -> 'a t -> 'a t val filteri : (int -> 'a -> bool) -> 'a t -> 'a t val take : int -> 'a t -> 'a t val drop : int -> 'a t -> 'a t val take_while : ('a -> bool) -> 'a t -> 'a t val drop_while : ('a -> bool) -> 'a t -> 'a t val partition : ('a -> bool) -> 'a t -> 'a t * 'a t val partition_map : ('a -> ('b, 'c) Either.t) -> 'a t -> 'b t * 'c t val assoc : 'a -> ('a * 'b) t -> 'b val assoc_opt : 'a -> ('a * 'b) t -> 'b option val assq : 'a -> ('a * 'b) t -> 'b val assq_opt : 'a -> ('a * 'b) t -> 'b option val mem_assoc : 'a -> ('a * 'b) t -> bool val mem_assq : 'a -> ('a * 'b) t -> bool val remove_assoc : 'a -> ('a * 'b) t -> ('a * 'b) t val remove_assq : 'a -> ('a * 'b) t -> ('a * 'b) t val split : ('a * 'b) t -> 'a t * 'b t val combine : 'a t -> 'b t -> ('a * 'b) t val sort : ('a -> 'a -> int) -> 'a t -> 'a t val stable_sort : ('a -> 'a -> int) -> 'a t -> 'a t val fast_sort : ('a -> 'a -> int) -> 'a t -> 'a t val sort_uniq : ('a -> 'a -> int) -> 'a t -> 'a t val merge : ('a -> 'a -> int) -> 'a t -> 'a t -> 'a t val to_seq : 'a t -> 'aSeq.t val of_seq : 'aSeq.t -> 'a t end
List.fold_left
语法:
1
List.fold_left f acc lst
f:是一个“累积函数”,定义如何处理当前元素和累积值。 它的类型是 ('b -> 'a -> 'b),即接收当前累积值和当前元素,返回新的累积值。(顺序一定不能反)
( (acc, list_element) -> new_acc)
acc:是初始累积值('b)。
lst:是要处理的列表('a)。
从列表的左边开始,依次用 f 更新累积值。
例子:
用于实现之前的列表映射函数map:
1 2
let map f lst = List.rev (List.fold_left (fun acc x -> (f x) :: acc) lst []);;
List.fold_left
语法:
1
List.fold_right f lst acc
f:'a -> 'b -> 'b( (list_element, acc) -> new_acc)
lst:'a
acc:'b
从列表的右边开始,依次用f更新累积值。
List.rev
定义:
1
List.rev : 'alist -> 'alist
返回一个反转后的列表。
示例:
1 2
List.rev [1; 2; 3];; (* 结果: [3; 2; 1] *)
List.map
定义:
1
List.map : ('a -> 'b) -> 'alist -> 'blist
对列表中每个元素应用函数,按原顺序生成等长的新列表。
示例:
1 2 3 4 5
List.map (fun x -> x * x) [1; 2; 3];; (* 结果: [1; 4; 9] *)
letrec find p (L (x, ts)) = letrec finds = function | [] -> None | t :: tr -> match find p t with | Some x -> Some x | None -> finds tr in if p x thenSome x else finds ts
对树中所有标签应用函数 f,保持树结构不变:
1 2
letrec lmap f (L (x, ts)) = L (f x, List.map (lmap f) ts)
Balanced Trees
如果一棵树所有叶子的地址长度都相同,那么它是 balanced。换句话说,所有叶子在同一层。
Module
open:
open只是让名字在当前作用域里可直接使用,不会把这些定义变成当前模块的导出内容。
1 2 3 4 5 6 7 8 9
moduleA = structlet x = 1end (*module A : sig val x : int end*)
moduleB = struct openA let y = 2 end (*module B : sig val y : int end*)
include:
include会把另一个模块的定义包含进当前模块。
1 2 3 4 5 6
moduleC = struct includeA includeB end (*module C : sig val x : int val y : int end*)