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 are structured data, whose structure is defined inductively; a list is either:
[] (empty); orelt :: lst (cons)List “literals:”
Append operator: l1 @ l2 (so [1;2] @ [3;4] ≡ [1;2;3;4])
What about [1; "one"; '1']?
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’.
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
The inductive definition of lists makes recursion a “good fit:”
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 + 0 ≡ 62
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
What if we evaluate reverse [1; 2; …; 𝓃]?
reverse [2;3; …; 𝓃] @[1]
reverse [3; …; 𝓃] @[2]
⋮
reverse [] @[𝓃]
[𝓃; …; 3; 2] @ [1]
[𝓃; …; 3] @ [2]
⋮
[] @ [𝓃]
cs2041.org