lecture0
lecture0
Kihong Heo
1
Functional Programming?
• An expression with ;; in the REFL tells you the resulting value and its type
$ utop
# 42;;
- : int = 42
# 1 + 1 (* this is a comment *);;
- : int = 2
fi
Values
• Boolean operators
# x = y (* equal *)
# x <> y (* not equal *)
# x < y (* less than *)
# x <= y (* less than or equal *)
# x > y (* larger than *)
# x >= y (* larger than or equal *)
# x && y (* logical and *)
# X || y (* logical or *)
# ‘a’;;
- : char = ‘a’
# ‘a’ = ‘a’;;
- : bool = true
# “hello” = “hello”;;
- : bool = true
# “hello, “ ^ ”world!”;;
- : string = “hello, world!”
• e2 if e1 evaluates to true
• e3 if e1 evaluates to false
• Example:
• Function de nition
# let increment x = x + 1;;
val increment : int -> int = <fun>
# increment 0;;
- : int = 1
• Application-style: e0 e1 e2 … en
where e0 is a function and e1 through en are the arguments
square (inc 5)
• Pipeline-style: “values are sent through the pipeline from left to right”
# let id x = x;;
id : ‘a -> ‘a = <fun>
• ‘a, ‘b, … are type variables that stand for unknown type
# let add x y = x + y
val add : int -> int -> int = <fun>
# add5 2;;
- : int = 7
• “Functional”!
# let x = 42 in x + 1
- : int = 43
• Let bindings are in e ect only in the block of code in which they occur
let x = 42 in
(* y is not meaningful here *)
x
+
(let y = "3110" in
(* y is meaningful here *)
int_of_string y)
# [1; 2; 3];;
- : int list = [1; 2; 3]
# [true; false; false];;
- : bool list = [true; false; false]
# [[1;2;3];[4;5]];;
- : int list list = [[1;2;3];[4;5]];;
• In principle, there are only two ways to build a list: nil ([]) and cons (::)
# [] (* nil means the empty list*) ;;
- : ‘a list
# 1::[2; 3] (* cons prepends an elem to a list *);;
- : int list [1; 2; 3]
# 1::2::3::[] (* conceptually the same as above *);;
- : int list [1; 2; 3]
• Remember that there are only two cases: nil and cons (head and tail)
(* compute the sum of an int list *)
let rec sum lst =
match lst with
| [] -> 0
| h::t -> h + sum t
# (1, 2, 10);;
- : int * int * int = (1, 2, 10)
# (true, “Hello”);;
- : bool * string = (true, "Hello")
• Examples:
(* OK *)
let thrd t =
match t with
let logical_and x y =
| (x, y, z) -> z
match (x, y) with
| (true, true) -> true
(* good *)
| (_, _) -> false
let thrd t =
let (x, y, z) = t in z
let logical_or x y =
match (x, y) with
(* better *)
| (true, _)
let thrd t =
| (_, true) -> true
let (_, _, z) = t in z
| (_, _) -> false
(* best *)
let thrd (_, _, z) = z
(* good *)
let get_sid m =
match m with
| { name=_; sid=s } -> s
(* better *)
let get_sid m =
match s with
| { sid } -> sid
(* best *)
let get_sid s = s.sid
• similar to typedef in C
# None;;
- : ‘a option
let extract o =
match o with
| Some i -> string_of_int i
| None -> “”
# let d = Tue;;
val d : day = Tue
let int_of_day d =
match d with
| Sun -> 1
| Mon -> 2
| Tue -> 3
| Wed -> 4
| Thr -> 5
| Fri -> 6
| Sat -> 7
let good_day d =
match m with
| Sun | Sat -> true
| _ -> false
type shape =
| Point of point
| Circle of point * float (* center and radius *)
| Rect of point * point (* lower-left and
upper-right corners *)
type shape =
| Point of point
| Circle of point * float (* center and radius *)
| Rect of point * point (* lower-eft and
upper-right corners *)
let area s =
match s with
| Point _ -> 0.0
| Circle (_, r) -> pi *. (r ** 2.0) (* ** means power *)
| Rect ((x1, y1), (x2, y2)) ->
let w = x2 -. x1 in
let h = y2 -. y1 in
w *. h
# ();;
- : unit = ()
# print_endline;;
- : string -> unit = <fun>
# print_endline “Hi”;;
Hi
- : unit = ()
exception Division_by_zero
exception Failure of string
let r =
try div x y with
| Division_by_zero -> 0
| Not_implemented -> -1
let empty = []
let is_empty s = (s = [])
let push x s = x :: s
let peek = function
| [] -> raise Empty
| x::_ -> x
let pop = function
| [] -> raise Empty
| _::xs -> xs
end
module B = IncX(A)
(* B.x is 1 *)
• http://caml.inria.fr/pub/docs/manual-ocaml/libref
• https://github.com/ocaml/ocaml/tree/trunk/stdlib
• http://caml.inria.fr/pub/docs/manual-ocaml/libref/Stdlib.html
• http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html
(* val fold_left : (’a -> ‘b -> ‘a) -> ‘a -> ‘b list -> ‘a *)
let sum = List.fold_left (+) 0 lst
let sum_of_squre = List.fold_left (fun acc x -> acc + x * x) 0 lst
• http://caml.inria.fr/pub/docs/manual-ocaml/libref/Set.html
(* val empty : t *)
let emptyset = PairSet.empty
• Searching
(* val mem : elt -> t -> bool *)
let membership = PairSet.mem (1, 2) x
• http://caml.inria.fr/pub/docs/manual-ocaml/libref/Map.html
(* val empty : ’a t *)
let emptymap = PairMap.empty
• Searching
(* val mem : key -> ’a t -> bool *)
let membership = PairMap.mem (1, 2) x
• Sparrow: https://github.com/prosyslab/sparrow
• Infer: https://github.com/facebook/infer
• OCamlgraph: https://github.com/backtracking/ocamlgraph