ML Crash Course

Lecture 2 - Week 1 - September 26, 2016


Deconstruct/unpack a tuple:

let (x, y, z) = (2 + 3, "a" ^ "B", 1::[2]);;
  • Note: A tuple may be composed of elements of different types. But a list must be homogenous.

Swap a pair:

let (x, y) = (0, 1) in (y, x);;

Deconstruct a list:

In general, using this pattern outside of pattern matching is dangerous and should be avoided.

let (h::t) = [1;2;3];;
val h : int = 1
val t : int list = [2; 3]

The match construct

match l with
    |  [] -> true
    |  h::t -> false;;
  • This pattern matches any list that starts with true
true :: _ -> false
  • All the branches under the match statement must return the same type (so ocaml type system can predict it)

Functions

The fun keyword

Takes arguments (listed on the left-hand side of ->) and returns the expression on the right-hand side of ->.

Increment an integer

let inc = (fun x -> x + 1);;

Swap a pair

let swap = fun (a, b) -> (b, a);;

A function that returns true if the given list is empty

let is_empty = fun l -> 
    match l with
    | [] -> true
    | _::_ -> false

Without the fun keyword

is_empty without the fun keyword

let is_empty l = 
    match l wth
    | [] -> true
    | _::_ -> false

More examples with Pattern Matching

Checking if the booleans are the same

let booleans_same = fun (b1, b2) ->
    match (b1, b2) with
    | (true, true) -> true
    | (true, false) -> false
    | (false, true) -> false
    | (false, false) -> true

This is equivalent to the previous function, except it utilizes a short-cut

let booleans_same = fun (b1, b2) ->
    match (b1, b2) with
    | (true, true) -> true
    | (false, false) -> true
    | _ -> false

NOTE: ocaml deduces the input types by checking the type on the left-hand side of each branch.

Carrying (?)

This technique involves returning a function to chain together inputs until all inner functions have been resolved.

# let plus = fun x -> fun y -> x + y
# let plusThree = (plus 3) 
# plusThree 5
- : int = 8

XXX: Can we use this in listReverse for Programming Assignment #1?

Negating a boolean function (Carrying a function)

# let neg = fun f -> fun x -> not (f x)
# neg (fun n -> n = 0) 0;;
- : bool = false

The type of the above function is:

neg:
('a -> bool) -> 'a -> bool

Without carrying (?)

let neg f

Homework #1

A function that filters a list (similar to Python’s builtin filter)

let rec filter f l = 
    match l with
    | [] -> []
    | (h::t) -> 
        let t' = (filter f t) in 
        if f h then h::t' else t';;

t’ is the filtered tail, and if h should stay, then we add it to the head of t’.