(* These notes cover some of the aspects of OCaml that we will be using that were NOT covered in 330. If you want a more thorough tutorial on OCaml, see: http://ocaml.org/learn/tutorials/ - DVH, 1.29.15 *) (***********************************************************************) (* Module type: interface for code *) module type SET = sig type 'a set val mt : 'a set val add : 'a -> 'a set -> 'a set val has : 'a set -> 'a -> bool val union : 'a set -> 'a set -> 'a set end ;; (***********************************************************************) (* Modules implementing an interface. *) (* Sets implemented with lists. *) module Set_1 : SET = struct type 'a set = 'a list let mt : 'a set = [] let add (x : 'a) (xs : 'a set) : 'a set = x :: xs let rec has (xs : 'a set) (x : 'a) : bool= match xs with | [] -> false | x'::xs -> x=x' || has xs x let union (xs : 'a set) (ys : 'a set) : 'a set = xs @ ys end ;; (* Sets implemented with functions. *) module Set_2 : SET = struct type 'a set = 'a -> bool let mt : 'a set = fun x -> false let add (x : 'a) (xs : 'a set) = fun y -> (x=y) || xs x let has (xs : 'a set) (x : 'a) : bool = xs x let union (xs : 'a set) (ys : 'a set) : 'a set = fun x -> xs x || ys x end ;; (***********************************************************************) (* Functors: functions from modules to modules *) module MakeFancySet (Set : SET) = struct include Set (* alternative: open Set uses but doesn't include *) let rec list_to_set (xs : 'a list) : 'a set = match xs with | [] -> mt | x :: xs -> add x (list_to_set xs) end ;; module FancySet_1 = MakeFancySet(Set_1);; module FancySet_2 = MakeFancySet(Set_2);; (***********************************************************************) (* Polymorphic variants: like variants but extensible *) (* Variants are always part of a name union *) type f = | Foo of int | Bar of float * int;; (* Polymorphic variants can be a part of arbitrary unions *) `Foo;; let next light = match light with | `Red -> `Green | `Green -> `Yellow | `Yellow -> `Red ;; let f x = match x with | `R y -> y ;; type expr = | Int of int | Plus of expr * expr ;; let rec eval (e : expr) : int = match e with | Int i -> i | Plus (e1, e2) -> eval e1 + eval e2 ;;