### copy sec04 from spring, but worksheet and slides are in Google Drive

parent 6b1044ae
 (* CSE 341, Section 4, Completed/Solution Code *) (* mutual recursion, just since we haven't shown it to you *) (* can do any finite state machine this way -- this one checks for strictly alternating even/odd mutual recursion is often not tail-recursive, but for finite state machines it is *) let rec start xs = match xs with | [] -> true | i::xs' -> if i mod 2 = 0 then saw_even xs' else saw_odd xs' and saw_even xs = match xs with | [] -> true | i::xs' -> i mod 2 = 0 && saw_odd xs' and saw_odd xs = match xs with | [] -> true | i::xs' -> i mod 2 <> 0 && saw_even xs' (* style above is correct, but we could if we really had to use first-class functions to encode mutual recursion by having earlier functions take function arguments and then calling them with later functions *) let saw_even2 f xs = match xs with | [] -> true | i::xs' -> i mod 2 <> 0 && f xs' let rec saw_odd2 xs = match xs with | [] -> true | i::xs' -> i mod 2 = 0 && saw_even2 saw_odd2 xs' let start2 xs = match xs with | [] -> true | i::xs' -> if i mod 2 = 0 then saw_even2 saw_odd2 xs' else saw_odd2 xs' (* module system *) (* NO CODE CAN DEPEND ON ANYTHING NOT IN THE MODULE TYPE! *) module type NONEGINT = sig type t val mknni : int -> t option val add : t -> t -> t (* why not t -> t -> int or t -> t -> t option? *) val mul : t -> t -> t val sub : t -> t -> t option val to_int : t -> int (* why not t -> t ? *) end module NonNegInt : NONEGINT = struct type t = int let mknni i = if i < 0 then None else Some i let add a b = a + b let mul a b = a * b (* why not mknni (a * b) ? *) let sub a b = mknni (a - b) (* why not a - b ? *) let to_int a = a (* external world doesn't know this "is it" *) end (* we may not have time for this longer example below, but it's a nice example we might give an overview of *) module type NONEMPTYLIST = sig type 'a t val single : 'a -> 'a t val cons : 'a -> 'a t -> 'a t val tl : 'a t -> 'a t val hd : 'a t -> 'a val len : 'a t -> int val map : ('a -> 'b) -> 'a t -> 'b t end module Nel_A : NONEMPTYLIST = struct type 'a t = | Single of 'a | Cons of 'a * 'a t let single x = Single x let cons x xs = Cons (x,xs) let tl xs = match xs with | Single _ -> failwith "tl of one-element list" | Cons(_,xs') -> xs' let hd xs = match xs with | Single x -> x | Cons(x,_) -> x let rec len xs = match xs with | Single _ -> 1 | Cons(_,xs') -> 1 + len xs' let rec map f xs = match xs with | Single x -> Single (f x) | Cons (x,xs') -> Cons(f x, map f xs') end module Nel_B : NONEMPTYLIST = struct type 'a t = 'a * ('a list) let single x = (x,[]) let cons x (y,xs) = (x,y::xs) let tl xs = match xs with | (_,[]) -> failwith "tl of one-element list" | (_,y::ys) -> (y,ys) let hd = fst let len (_,xs') = 1 + List.length xs' let map f (x,xs') = (f x, List.map f xs') end module Nel_C : NONEMPTYLIST = struct type 'a t = 'a list let single x = [x] let cons x xs = x::xs let tl xs = match xs with | [] -> failwith "impossible -- should never happen" | x::[] -> failwith "tl of one-element list" | x::xs' -> xs' let hd = List.hd let len = List.length let map = List.map end
 (* CSE 341, Section 04 *) (* # Currying *) (* a) *) let filter_by_example f x = List.filter (fun x' -> f x = f x') (* b) *) let same_size_as xs = filter_by_example List.length xs (* “bad style” to avoid the value restriction *) (* c) *) (* helper function: takes a string and returns list of its letters*) let explode str = let rec exp_helper i cs = if i < 0 then cs else exp_helper (i - 1) (str.[i]::cs) in exp_helper (String.length str - 1) [] let count_o s = List.fold_left (fun acc x -> if x = 'o' then acc + 1 else acc) 0 (explode s) (* d) *) let silly_application = filter_by_example count_o "dogsarecool" (* e) *) let contains x = List.fold_left (fun acc x' -> acc || x' = x) false (* f) *) let rec filter_unique f prev xs = match xs with | [] -> [] | x'::xs' -> let result = f x’ in if contains result prev then filter_unique f prev xs' else x' :: filter_unique f (result :: prev) xs' (* g) *) let unique_sums xs = filter_unique List.length [] xs (* h) *) let all_that_contain x = (List.filter (contains x)) (* i) *) let even_only = List.map (List.filter (fun x -> x mod 2 = 0)) (* j) *) let even_only_not_empty xs = List.filter (fun xs' -> xs' <> []) (even_only xs) (* # Modules *) (* (a) *) module type NONEGINT = sig type t val mknni : int -> t option (* why not t -> t -> int or t -> t -> t option? *) val add : t -> t -> t val mul : t -> t -> t val sub : t -> t -> t option val to_int : t -> int (* why not t -> t ? *) end (* (b) *) module type RATIONAL = sig type rational exception BadFrac val to_string : rational -> string val add : rational * rational -> rational val whole : int -> rational val make_frac : int * int -> rational end module Rational : RATIONAL = struct type rational = int * int exception BadFrac let to_string (x,y) = "" (* fake body *) let whole i = (i,1) let add ((a,b),(c,d)) = (0,0) (* fake body *) let make_frac (x,y) = (2,2) (* fake body *) end
 (* CSE 341, Section 04 *) (* # Currying *) (* Uncomment and fill in the functions below. *) (* a) *) (* let filter_by_example *) (* b) *) (* let same_size_as *) (* c) *) (* let count_o *) (* d) *) (* let silly_application *) (* e) *) (* let contains *) (* f) *) (* let rec filter_unique *) (* g) *) (* let unique_sums *) (* h) *) (* let all_that_contain *) (* i) *) (* let even_only *) (* j) *) (* let even_only_not_empty *) (* # Modules *) (* (a) *) module type NONEGINT = sig (* Your code here *) end (* (b) *) module type RATIONAL = sig (* Your code here *) end module Rational : RATIONAL = struct (* Your code here *) end
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment