(* 22c:185, Fall 2006 *) (* Ocaml examples seen in class *) (* simple types *) 3;; 3 + 5 ;; 4 - 2 ;; 3.0 ;; "hi" ;; "hi" ^ " there" ;; true;; not(true);; (* tuple types *) (1,3) ;; (3,4,5) ;; (3,"pp",4.3) ;; (* declarations of values and functions *) let a = 3 ;; a ;; let b = 4+a ;; let c:string = "55" ;; (* let c:int = "55" ;; *) let suc (n:int) = n + 1 ;; let suc n = n +. 1.0 ;; let suc n = n + 1 ;; (* syntactic sugar for *) let suc = function n -> n + 1 ;; suc(3) ;; suc 3;; (* suc suc 3;; *) suc (suc 3) ;; let suc n = n + 1 ;; let i_square (n:int):int = n * n ;; i_square 4;; (* i_square 4.0;; let r_cube n = n *. (i_square n) ;; *) let a = 5 ;; let f x = a + x ;; f 1 ;; let a = 2 ;; f 1 ;; let add (m,n) = m + n ;; add (3,4) ;; (* Pattern matching *) let t = (3,5,2) ;; let (x1,x2,x3) = t ;; let (y1,y2,_) = t ;; let t = ((2,3),5,(6,2)) ;; let (_, x, _) = t ;; let (_, _, (x,_)) = t ;; let sum (x,y) = x+y;; let psum ((x1,x2), (y1,y2)) = (x1+y1,x2+y2) ;; psum ((1,2), (3,4)) ;; let conv n = match n with 0 -> "zero" | 1 -> "one" | 2 -> "two" | _ -> "enough already" ;; let conv n = match (n*n+1) with 0 -> "zero" | 1 -> "one" | 2 -> "two" | _ -> "enough already" ;; let bothZero (x1,x2) = if not (x1 = 0) then false else if x2 = 0 then true else false ;; let bothZero (x,y) = match (x,y) with (0,0) -> true | (_,_) -> false ;; let bothZero pair = match pair with (0,0) -> true | (_,_) -> false ;; (* recursive functions *) (* let fact n = if n = 0 then 1 else n*(fact (n - 1)) ;; *) let rec fact n = if n = 0 then 1 else n*(fact (n - 1)) ;; let rec fact n = match n with 0 -> 1 | _ -> n*(fact (n - 1)) ;; (* alternative syntax for function declarations with pattern matching *) let rec fact = function 0 -> 1 | n -> n*(fact (n - 1)) ;; let bothZero = function (0,0) -> true | (_,_) -> false ;; (* scoping *) let n = 3 in fact n ;; (* n;; *) let n = 3 in let m = 1+n in fact (n - m) ;; (* multi-argument functions *) let add (m,n) = m + n ;; let add' m n = m + n ;; add (3,5) ;; add' 3 5 ;; (* add' (3, 5) ;; *) add' (add' 3 5) 4 ;; add' 2;; (* higher-order functions *) let add' m n = m + n ;; let add1 = add' 1 ;; add1 5;; add' 1 5;; (add' 1) 5;; let apply f x = f x ;; apply add1 3;; let applyTwice f x = f (f x) ;; applyTwice add1 3;; let compose f g x = f (g x) ;; let square x = x * x ;; compose add1 square 3 ;; let add2 = compose add1 add1 ;; add2 3;; let add4 = compose (add' 1) (add' 3) ;; add4 6;; let twice f = compose f f ;; let add2 = twice (add' 1) ;; add2 3;; (* Lists *) [];; [3;5;6];; ["dd"; "sdf"];; [(1,2);(1,4)];; [[3;1];[];[4;5;6]];; (* [3; "sdf"];; *) [6];; 6::[];; 5::(6::[]);; 5::6::[];; (* 5::6;; *) List.hd [1;2;3];; List.tl [1;2;3];; let (h::t) = [1;2;3] ;; let (h::t) = (1::(2::(3::[]))) ;; let rec ilen (l:int list) = match l with [] -> 0 | (_::t) -> 1 + (ilen t);; ilen [1;2;3];; let rec len l = match l with [] -> 0 | (_::t) -> 1 + (len t);; len [1;2;3];; len ["a";"b"];; let rec len = function [] -> 0 | (_::t) -> 1 + (len t) ;; let rec append l m = match l with [] -> m | (h::t) -> h::(append t m) ;; append [1;2] [2;3;4];; let rec reverse = function [] -> [] | (h::t) -> append (reverse t) [h] ;; reverse [1;2;3];; let rec reverse = function [] -> [] | (h::t) -> let rt = reverse t in let hl = [h] in append rt hl ;; (* algebraic datatypes *) type month = Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec ;; Jan ;; let date = (Aug,5,1977);; let f = function Jan -> "this is January" | Feb -> "this is February" | _ -> "this is neither January nor February" ;; type btree = ET | Node of (int * btree * btree) ;; ET ;; let e = ET ;; let t1 = Node(3,e,e) ;; let t2 = Node(5,e,e) ;; let t3 = Node(10,t1,t2) ;; let t4 = Node(4,t3,e);; t4;; let newTree n = Node(n,ET,ET) ;; let root_value t = match t with (Node (v,_,_)) -> v | _ -> failwith "Empty tree" ;; root_value t1;; root_value e;; let left_child t = match t with (Node (_,t,_)) -> t | _ -> failwith "Empty tree" ;; let right_child t = match t with (Node (_,_,t)) -> t | _ -> failwith "Empty tree" ;; t3 ;; left_child t3 ;; let rec lookup n = function ET -> false | (Node (m,t1,t2)) -> if m = n then true else if (lookup n t1) then true else if (lookup n t2) then true else false ;; let rec lookup n = function ET -> false | (Node (m,t1,t2)) -> (m = n) or (lookup n t1) or (lookup n t2) ;; let rec insert n = function ET -> Node(n,ET,ET) | (Node (m,t1,t2)) -> if (n < m) then Node (m, (insert n t1), t2) else Node (m, t1, (insert n t2)) ;; let t = (Node(3,ET,(Node(5,ET,ET)))) ;; let t' = insert 4 t ;; let rec traverse = function ET -> [] | (Node (m,t1,t2)) -> let l1 = traverse t1 in let l2 = traverse t2 in l1@(m::l2) ;; traverse t' ;;