
CMSC 330: Organization of Programming Languages Functional Programming with Lists CMSC 330 - Spring 2017 1 Lists in OCaml • The basic data structure in OCaml – Lists can be of arbitrary length • Implemented as a linked data structure – Lists must be homogeneous • All elements have the same type • Operations – Construct lists – Destruct them via pattern matching CMSC 330 - Spring 2017 2 Constructing Lists Syntax • [] is the empty list (pronounced “nil”) • e1::e2 prepends element e1 to list e2 – Operator :: is pronounced "cons" (both from LISP) – e1 is the head, e2 is the tail • [e1;e2;…;en] is syntactic sugar for e1::e2::…::en::[] Examples 3::[] (* The list [3] *) 2::(3::[]) (* The list [2; 3] *) [1; 2; 3] (* The list 1::(2::(3::[])) *) CMSC 330 - Spring 2017 3 Constructing Lists Evaluation • [] is a value • To evaluate e1::e2, evaluate e1 to a value v1, evaluate e2 to a (list) value v2, and return v1::v2 Consequence of the above rules: • To evaluate [e1;…;en], evaluate e1 to a value v1, ...., evaluate en to a value vn, and return [v1;…;vn] CMSC 330 - Spring 2017 4 Examples # let y = [1; 1+1; 1+1+1] ;; val y : int list = [1; 2; 3] # let x = 4::y ;; val x : int list = [4; 1; 2; 3] # let z = 5::y ;; val z : int list = [5; 1; 2; 3] # let m = “hello”::”bob”::[];; val z : string list = [“hello”; “bob”] CMSC 330 - Spring 2017 5 Typing List Construction Polymorphic type: Nil: like a generic type in Java []: 'a list i.e., empty list has type t list for any type t Cons: If e1 : t and e2 : t list then e1::e2 : t list With parens for clarity: If e1 : t and e2 : (t list) then (e1::e2) : (t list) CMSC 330 - Spring 2017 6 Examples # let x = [1;"world”] ;; This expression has type string but an expression was expected of type int # let m = [[1];[2;3]];; val y : int list list = [[1]; [2; 3]] # let y = 0::[1;2;3] ;; val y : int list = [0; 1; 2; 3] # let w = [1;2]::y ;; This expression has type int list but is here used with type int list list • The left argument of :: is an element, the right is a list • Can you construct a list y such that [1;2]::y makes sense? CMSC 330 - Spring 2017 7 Lists in Ocaml are Linked • [1;2;3] is represented above – A nonempty list is a pair (element, rest of list) – The element is the head of the list – The pointer is the tail or rest of the list • ...which is itself a list! • Thus in math (i.e., inductively) a list is either – The empty list [ ] – Or a pair consisting of an element and a list • This recursive structure will come in handy shortly CMSC 330 - Spring 2017 8 Consider a Linked List in C struct list { int elt; struct list *next; elt next }; … struct list *l; … i = 0; elt next while (l != NULL) { i++; l = l->next; } elt next CMSC 330 - Spring 2017 9 Lists of Lists • Lists can be nested arbitrarily – Example: [ [9; 10; 11]; [5; 4; 3; 2] ] • (Type int list list) CMSC 330 - Spring 2017 10 Lists are Immutable • No way to mutate (change) an element of a list • Instead, build up new lists out of old, e.g., using :: let x = [1;2;3;4] let y = 5::x let z = 6::x x y 1 2 3 4 5 z 6 CMSC 330 - Spring 2017 11 Quiz 1 What is the type of the following expression? [1.0; 2.0; 3.0; 4.0] A. array B. list C. int list D. float list CMSC 330 - Spring 2017 12 Quiz 1 What is the type of the following expression? [1.0; 2.0; 3.0; 4.0] A. array B. list C. int list D. float list CMSC 330 - Spring 2017 13 Quiz 2 What is the type of the following expression? 31::[3] A. int B. int list C. int list list D. error CMSC 330 - Spring 2017 14 Quiz 2 What is the type of the following expression? 31::[3] A. int B. int list C. int list list D. error CMSC 330 - Spring 2017 15 Quiz 3 What is the type of the following expression? [[[]; []; [1.3;2.4]]] A. int list B. float list list C. float list list list D. error CMSC 330 - Spring 2017 16 Quiz 3 What is the type of the following expression? [[[]; []; [1.3;2.4]]] A. int list B. float list list C. float list list list D. error CMSC 330 - Spring 2017 17 Quiz 4 What is the type of the following definition? let f x = x::(0::[ ]) A. int -> int B. int list C. int list -> int list D. int -> int list CMSC 330 - Spring 2017 18 Quiz 4 What is the type of the following definition? let f x = x::(0::[ ]) A. int -> int B. int list C. int list -> int list D. int -> int list CMSC 330 - Spring 2017 19 Pattern Matching • To pull lists apart, use the match construct • Syntax match e with | p1 -> e1 | … | pn -> en • p1...pn are patterns made up of [], ::, constants, and pattern variables (which are normal OCaml variables) • e1...en are branch expressions in which pattern variables in the corresponding pattern are bound CMSC 330 - Spring 2017 20 match e with Pattern Matching Semantics | p1 -> e1 | … | pn -> en • Evaluate e to a value v • If p1 matches v, then evaluate e1 to v1 and return v1 • ... • Else if pn matches v, then evaluate en to vn and return vn • Else, no patterns match: raise Match_failure exception • (When evaluating branch expression ei, any pattern variables in pi are bound in ei, i.e., they are in scope) CMSC 330 - Spring 2017 21 Pattern Matching Example let is_empty l = match l with [] -> true | (h::t) -> false Example runs • is_empty [] (* evaluates to true *) • is_empty [1] (* evaluates to false *) • is_empty [1;2](* evaluates to false *) CMSC 330 - Spring 2017 22 Pattern Matching Example (cont.) let hd l = match l with (h::t) -> h • Example runs – hd [1;2;3](* evaluates to 1 *) – hd [2;3] (* evaluates to 2 *) – hd [3] (* evaluates to 3 *) – hd [] (* Exception: Match_failure *) CMSC 330 - Spring 2017 23 Quiz 5 To what does the following expression evaluate? match [“zar”;“doz”] with [] -> “kitteh” | h::t -> h A. “zar” B. “doz” C. “kitteh” D. [] CMSC 330 - Spring 2017 24 Quiz 5 To what does the following expression evaluate? match [“zar”;“doz”] with [] -> “kitteh” | h::t -> h A. “zar” B. “doz” C. “kitteh” D. [] CMSC 330 - Spring 2017 25 "Deep" pattern matching • You can nest patterns for more precise matches – a::b matches lists with at least one element • Matches [1;2;3], binding a to 1 and b to [2;3] – a::[] matches lists with exactly one element • Matches [1], binding a to 1 • Could also write pattern a::[] as [a] – a::b::[] matches lists with exactly two elements • Matches [1;2], binding a to 1 and b to 2 • Could also write pattern a::b::[] as [a;b] – a::b::c::d matches lists with at least three elements • Matches [1;2;3], binding a to 1, b to 2, c to 3, and d to [] • Cannot write pattern as [a;b;c]::d (why?) CMSC 330 - Spring 2017 26 Pattern Matching – Wildcards • An underscore _ is a wildcard pattern – Matches anything – But doesn’t add any bindings – Useful to hold a place but discard the value • i.e., when the variable does not appear in the branch expression • In previous examples – Many values of h or t ignored – Can replace with wildcard _ CMSC 330 - Spring 2017 27 Pattern Matching – Wildcards (cont.) • Code using _ – let is_empty l = match l with [] -> true | (_::_) -> false – let hd l = match l with (h::_) -> h – let tl l = match l with (_::t) -> t • Outputs – is_empty[1](* evaluates to false *) – is_empty[ ](* evaluates to true *) – hd [1;2;3] (* evaluates to 1 *) – tl [1;2;3] (* evaluates to [2;3] *) – hd [1] (* evaluates to 1 *) – tl [1] (* evaluates to [ ] *) CMSC 330 - Spring 2017 28 Pattern Matching – An Abbreviation • let f p = e, where p is a pattern – is shorthand for let f x = match x with p -> e • Examples – let hd (h::_) = h – let tl (_::t) = t – let f (x::y::_) = x + y – let g [x; y] = x + y • Useful if there’s only one acceptable input CMSC 330 - Spring 2017 29 match e with Pattern Matching Typing | p1 -> e1 | … • If e and p1, ..., pn each have type ta | pn -> en • and e1, ..., en each have type tb • Then entire match expression has type tb • Examples type: ‘a list -> ‘a type: int list -> int ta = ‘a list let hd l = let rec sum l = match l with match l with (h::_) -> h tb [] -> 0 tb | (h::t) -> h+sum t tb = ‘a ta = int list tb = int CMSC 330 - Spring 2017 30 Polymorphic Types • The sum function works only for int lists • But the hd function works for any type of list – hd [1; 2; 3] (* returns 1 *) – hd ["a"; "b"; "c"] (* returns "a" *) • OCaml gives such functions polymorphic types – hd : 'a list -> 'a – this says the function takes a list of any element type 'a, and returns something of that same type • These are basically generic types in Java – 'a list is like List<T> CMSC 330 - Spring 2017 31 Examples Of Polymorphic Types • let tl (_::t) = t # tl [1; 2; 3];; - : int list = [2; 3] # tl [1.0; 2.0];; - : float list = [2.0] (* tl : 'a list -> 'a list *) • let fst x y = x # fst 1 “hello”;; - : int = 1 # fst [1; 2] 1;; - : int list = [1; 2] (* fst : 'a -> 'b -> 'a *) CMSC 330 - Spring 2017 32 Examples Of Polymorphic Types • let hds (x::_) (y::_) = x::y::[] # hds [1; 2] [3; 4];; - : int list = [1; 3] # hds [“kitty”] [“cat”];; - : string list = [“kitty”; “cat”] # hds [“kitty”] [3; 4] -- type error (* hds: 'a list -> ’a list -> 'a list *) • let eq x y = x = y (* let eq x y = (x = y) *) # eq 1 2;; - : bool = false # eq “hello” “there”;; - : bool = false # eq “hello” 1 -- type error (* eq : 'a -> ’a -> bool *) CMSC 330 - Spring 2017 33 Quiz 6 What is the type of the following function? let f x y = if x = y then 1 else 0 A.
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages43 Page
-
File Size-