Lists are the basic data structure in OCaml
Lists are the basic data structure in OCaml
(* lists.ml *)
[1;2;3;4;5]
List Creation
(* lists-1.ml *)
e1::e2::[]
Lists are the basic data structure in OCaml
(* lists-1.ml *)
e1::e2::[]
Have type list
When evaluating, go right to left
(* let.ml *)
let x = e1 in e2
Let expressions are expressions
Expressions have a type
(* let-type.ml *)
(let x = e1:t1 in e2:t2):t2
Can be nested
(* let-nest.ml *)
let x = 3 in let y = 4 in x + y
Can be used for local variables
(* let-vars.ml *)
let area r =
let pi = 3.14 in
pi *. r *. r
Variables will be shadowed
(* let-shadowing.ml *)
let x = 3 in let x = 5 in x + 4
Can deconstruct lists
(* match-nest.ml *)
let x = [1;2;3] in match x with
|[] -> true
|h::t -> false
Match looks at patterns of structure
Match looks at patterns of structure
Common Patterns
(* match-patterns.ml *)
let empty x = in match x with
|[] -> true (* empty *)
|a::[] -> false (* list of size 1 *)
|h::t -> false (* list at least size 1 *)
|_ -> false (* wildcard *)
Variables are bound on order
Last item is a list
Match looks at patterns of structure
Can be put as argument
(* match-function.ml *)
let car (h::_) = h;;
let cdr (_::t) = t;;
Match looks at patterns of structure
Can be Polymorphic
(* match-polymorphic.ml *)
let car lst = match lst with
[] -> []
h::_ -> h;;
(* lst has type 'a list *)
let rec sum lst = match lst with
[]-> 0
|h::t -> h + sum t;;
(* h has type int list *)
Used commonly in recursive functions
(* match-rec-functions.ml *)
let rec sum lst = match lst with
[]-> 0
|h::t -> h + sum t;;
let rec negate lst = match lst with
[]-> []
|h::t -> -h + negate t;;
let rec last lst = match lst with
[x]-> x
|h::t -> last t;;
let rec append l m = match l with
[]-> m
|h::t -> x :: (append t m)
let rec rev l = match l with
|[] -> []
| h::t -> append (rev t) (h::[])
(* rev is O(n^2) *)
(* can you do better? *)
Like Lists, but not really
(* tuples.ml *)
(1,2)
Tuples have a set Type
(* tuples-type.ml *)
(1,2) (* int * int *)
(1,"string",2.3) (* int * string * float *)
('a','b') (* char * char *)
['a';'b'] (* char list *)
[(1,2);(3,4)] (* (int * int) list *)
([1;2],[3;4]) (* int list * int list *)
Can Pattern Match
(* tuples-match.ml *)
let add t = match t with
(a,b) -> a + b
Remember Tuples have a type based on size
(* tuples-match-err.ml *)
let add t = match t with
(a,b) -> a + b
|(a,b,c) -> a + b + c
Like a weird hash
(* records.ml *)
type data = { month: string; dat: int; year: int };;
let today = { day=29; year=2020; month="feb"};;
O in OCaml stands for Object
(* record-access-1.ml *)
print_string today.month
Can also pattern match
(* record-access-2.ml *)
let { month=_; day = d} = today in
print_int d
We just saw this syntax
(* ud-types-alias.ml *)
type ilist = int list;;
let f x:ilist = [1;2;3;4];;
Ultimately not really useful in this form
Variant Types are more useful
(* ud-variants.ml *)
type parity = Even | Odd
Like an enum
(* pm-variants.ml *)
let swap x = match x with
Even -> Odd
|Odd -> Even
Can be Pattern Matched
Can Hold Data
(* ud-variants-1.ml *)
type parity = Even of int | Odd of int
Can still be Pattern Matched
(* pm-variants-1.ml *)
let add x = match x with
Even(x) -> Odd(x+1)
|Odd(x) -> Even(x+1)
Can Hold Data
Can be different
(* ud-variants-2.ml *)
type shape = Rect of int * int | Circle of float
Can still be Pattern Matched
(* pm-variants-2.ml *)
let area s = match s with
Rect (w,l) -> float_of_int (w*l)
|Circle r -> r *. r *. 3.14
Can be Recursive
(* llist.ml *)
type linked =
Item of string * linked
|Null;;
let head lst = match lst with
Item(x,_) -> x
|Null -> "";;
head (Item("Hello",Item("world", Null)));;
Can be generic
(* some_none.ml *)
type 'a option =
Some of 'a
|None
Built into OCaml