CSCI 2041

ADVANCED PROGRAMMING PRINCIPLES

Lists and polymorphism

OCaml programs

Expressions

A program is a sequence of expressions that are evaluated in order.

Every expression has a unique value and type.

We’ve seen primitive types and operators, let (rec) expressions, function values and types, and product types (tuples).

Ocaml has a language for specifying types: ->, *, 'a.

Structured data can be accessed through pattern matching.

Lists

Lists

Lists are structured data, whose structure is defined inductively; a list is either:

  • [] (empty); or
  • elt :: lst (cons)

List “literals:”

[]
1::2::3::[] (* ≡ 1::(2::(3::[])) ≡ [1; 2; 3] *)
"happy"::"doc"::"sneezy"::"sleepy"::"grumpy"::"dopey"::"bashful"::[]
(* ≡ ["happy"; "doc"; "sneezy"; "sleepy"; "grumpy"; "dopey"; "bashful"] *)

Append operator: l1 @ l2 (so [1;2] @ [3;4] ≡ [1;2;3;4])

What about [1; "one"; '1']?

list type

The type of [] : 'a list is a type constructor: for any type τ it constructs a new type τ list.

What is the type of [[1; 2; 3]; [4; 5]]?

'a list is another example of a polymorphic type.

What about [[]; 3]?

'a can only match one type “at a time:” once we decide 'a = 'b list it cannot also match ‘int’.

destructuring lists

Pattern matching on lists uses the [] and :: constructors:

match [1;3] with h::t -> h

1

match [1;3] with h::t -> t

≡ [3]

match [3] with h::t -> t

≡ []

let is_empty = function [] -> true | _::_ -> false

Computing on lists

The inductive definition of lists makes recursion a “good fit:”

let rec sum_int = function
| [] -> 0
| x::xs -> x + (sum_int xs)

Evaluating sum_int [3;17;42]:

sum_int 3::(17::42::[])
3 + (sum_int 17::(42::[]))
3 + (17 + (sum_int 42::[]))
3 + (17 + (42 + (sum_int [])))
3 + 17 + 42 + 062

More examples


let rec length: 'a list -> int =


let rec append : 'a list -> 'a list -> 'a list


let rec drop : int -> 'a list -> 'a list


Another example: reverse : 'a list -> 'a list

let rec reverse = function
| [] -> []
| h::t -> (reverse t) @ [h]

What if we evaluate reverse [1; 2; …; 𝓃]?

reverse [2;3; …; 𝓃] @[1]

reverse [3; …; 𝓃] @[2]

reverse [] @[𝓃]

[𝓃; …; 3; 2] @ [1]

[𝓃; …; 3] @ [2]

[] @ [𝓃]

cs2041.org

// reveal.js plugins