(***** EXPRESSION BASICS ******)
(* Note: type declarations have to be at the top level *)
type my_type = A of int | B of string
type int_option = Some of int | None
type int_list = Cons of int * int_list | Empty
type binary_tree = Leaf of int | Node of binary_tree * binary_tree
let main () =
(* Let expression with type annotation *)
let x : int = 2 in
(* Variable scoping *)
let y : int = x + 1 in
let x =
let x =
let x = 2 in
x + 1
in
x + 1
in
(* Type inference *)
let z = 3 in
(* let z : string = 3 in *)
(* Other types *)
let s : string = "hello world" in
let b : bool = false in
let n : float = 3.0 in
(* Functions *)
let add_one : int -> int = fun (n : int) -> n + 1 in
let add_one = fun n -> n + 1 in
let add_one (n : int) : int = n + 1 in
let add_one n = n + 1 in
(* Currying *)
let add_k k n = k + n in
let add_one = add_k 1 in
let add_five = add_k 5 in
(* Recursive functions *)
(* Note that equality is =, not == *)
let rec fact n =
if n = 0 then 1
else n * (fact (n - 1))
in
(* If statements *)
let x = if 3 > 2 then "true" else "not true" in
(* Helper functions to emulate loops *)
let is_prime n =
let rec check_num i =
if i = n then true
else if n mod i = 0 then false
else check_num (i + 1)
in
check_num 2
in
(* Match statements *)
let rec fib n =
match n with
| 0 -> 0
| 1 -> 1
| _ -> (fib (n - 1)) + (fib (n - 2))
in
(* EXERCISES:
* val clamp : int -> int -> int -> int
* clamp lower upper n = returns n clamped to range [lower, upper]
* val sum_to : int -> int
* sum_to n = adds all the numbers from 1 to n (don't use the closed form) *)
let clamp lower upper n =
if n < lower then lower
else if n > upper then upper
else n
in
let rec sum_to n =
if n = 0 then 0
else n + (sum_to (n - 1))
in
(****** COMPOSITE DATA TYPES *****)
(* Tuples *)
let tuple : int * string * int = (1, "two", 3) in
let (x, y, z) = tuple in
let n = match tuple with
| (_, _, 1) -> 1
| _ -> 2
in
(* Currying vs. tuples *)
let f (a, b) = a + b in
let f a b = a + b in
(* List *)
let l : int list = [1; 2; 3] in
let head (l : int list) : int = match l with
| [] -> raise (Failure ("No elements in list"))
| x :: l' -> x
in
let rec sum_list l =
match l with
| [] -> 0
| x :: l' -> x + (sum_list l')
in
(* EXERCISES:
* val map : int list -> (int -> int) -> int list
* map l f = returns l' with f applied to each element
*)
let rec map l f =
match l with
| [] -> []
| x :: l' -> (f x) :: (map l' f)
in
(* Option types *)
let try_div m n =
if n = 0 then None
else Some (m / n)
in
let () = match try_div 5 0 with
| Some n -> Printf.printf "%d\n" n
| None -> Printf.printf "bad div!\n"
in
(* Sum types *)
let l = 1 :: 2 :: [] in
let l' = Cons (1, Cons (2, Empty)) in
()
let () = main()