CMSC330

Ocaml Data Types

OCaml Data Types

Lists
Lets and Pattern Matching
Tuples, Records
Variants

Lists

Lists

Lists are the basic data structure in OCaml

  • Arbitrary Length
  • Homogenous
  • Implemented as a Linked List
  • Can be constructed and deconstructed

Lists are the basic data structure in OCaml


(* lists.ml *)
[1;2;3;4;5]
          
  • ; as seperator
  • Bracket Syntax
  • No indexing

List Creation


(* lists-1.ml *)
e1::e2::[]
          

Lists are the basic data structure in OCaml


(* lists-1.ml *)
e1::e2::[]
          
  • []- empty list (nil)
  • ::- cons
  • A list has a Head and Tail

Have type list

When evaluating, go right to left

Lets and Pattern Matching

Let Expressions

(* let.ml *)
let x = e1 in e2
          
  • Let expressions are not the same as let definitions
  • Bind local variables for e2
  • Scope is only for the body

Let expressions are expressions

Expressions have a type


(* let-type.ml *)
(let x = e1:t1 in e2:t2):t2
          
Let Expressions

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
          
Pattern Match

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

Pattern Match

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

Pattern Match

Match looks at patterns of structure

Can be put as argument


(* match-function.ml *)
let car (h::_) = h;;
let cdr (_::t) = t;;
          
Pattern Match

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 *)
          
Pattern Match

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? *)
          

Tuples and Records

Tuples

Like Lists, but not really


(* tuples.ml *)
(1,2)
          
  • Surrounded with ()
  • Seperated with ,
  • Heterogenous
  • Fixed size
Tuples

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 *)
          
Tuples

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
          
Records

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
          

Variants

User Defined Types

We just saw this syntax


(* ud-types-alias.ml *)
type ilist = int list;;
let f x:ilist = [1;2;3;4];;
          
  • Like a typedef
  • type keyword will allow for an alias

    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