Last Time Introduction Course Logistics Introduction to ML Base Types Tuples and Records Functions & Polymorphism See Harper’s Intro to ML Today Sign up to be ‘TA’ for a week More ML Data types Type abbreviations Exceptions Modules Mathematical Preliminaries Inductive Definitions Using SML/NJ Interactive mode is a good way to start learning and to debug programs, but… Type in a series of declarations into a “.sml” file Use “foo.sml” [opening foo.sml] … Val it = () : unit Larger Projects SML has its own built in interactive “make” Pros: It automatically does the dependency analysis for you No crazy makefile syntax to learn Cons: May be more difficult to interact with other languages or tools Compilation Manager sources.cm Group is a.sig b.sml c.sml a.sig b.sml c.sml % sml -OS.FileSys.chDir “~/courses/510/a2”; -CM.make(); looks for “sources.cm”, analyzes depdndencies [compiling…] compiles files in group [wrote…] saves binaries in ./CM/ -CM.make’ “myproj/”(); specify directory Lists Lists are defined in two ways: nil : ‘a list (empty list) :: : ‘a * ‘a list -> ‘a list 3 :: 4 :: 5 :: nil : int list (fn x => x) :: niil : (‘a -> ‘a) list 3 :: true :: nil : ? Abbreivation : [] (empty list) [x,y,z] (x :: y :: z :: nil) List Processing Fun length(nil) = 0 l length (x :: l) = 1 + length l Functions over lists are usually defined by case analysis (induction) over the structure of a list . nil . X :: ; Fun | div two nil = 0 || div two (x::nil) = 0 || div two (x :: y :: z) = 1 + | divtwo z List Processing Fun length l = case l of [] => 0 | _ :: l => | + length l; wild card pattern “don’t care” Other Patterns Fun lessThree x = case x of 0 | 1 | Z => true | z => false Fun first (a,b) = a; Fun snd (a,b) = b; Patterns can be Variables Integer, char, string constants Tuples Records Lists Wild cards And a few other things… Datatypes -datatype bool = true/false Datatypes can carry values: Datatype coin = penny | Nickel | Dime | Quarter | Loonie | Twonie Datatype bill = One | Five | Ten | Twenty Datatype money = Coin of coin | Bill of bill | Forgery of int Datatypes - Fun count money = case money of coin(x) => count_coin x | Bill (b) => count_bill b And count_coin c = case c of Penny => 1 | Nickel => 5 | … And count_bill b = (case b of One =>1 | Two =>2 | … > * 100 Pitfalls Datatype coin = penny | nickel; Val c = penny; Case c of nickel => true | Penny => false >? - case Nickel of Penny => true | Nickel => false; >? - case Nickel of Penny => case Nickel of Penny => true | Nickel => false | nickel => true >? Problem Set #1 Datatype digit = One | Two | … Datatype number = D of digit | … Type Abbreviations Type node = int; Type edges = node->node list; Type graph = node list * edges; Fun neighbours((g, n) : graph * node) * let val (_,e) * g in e n end; we may use the fact that the type graph is equivalent to node list * edges Exceptions Exception Head; Fun head nil = raise Head | head x :: +1 = x (head []) handle Head=> 3 Careful again: - :F e, then e2 else e3 handle Head =>3 nil :: nil :: nil :: nil : (‘a list) list [[1,2,3],[3,4,5]]:int list list Modules Signatures Structures Interfaces Implementations Functors Parameterized structures Functions from structures to structures Signatures Signautre QUEUE = signature name sig type ‘a queue exception Empty val empty : ‘a queue val insert : ‘a * ‘a queue Keywords -> ‘a queue delimit val remove : ‘a queue signature -> ‘a * ‘a queue end Signature Inclusion Signature QUEUE_EMPTY = sig include QUEUE val is_empty : ‘a queue -> bool End - equivalent to writing out QUEUE inside QUEUE_EMPTY Using Structures = Queue : Empty; > Queue.Empty : ‘a Queue.queue - val a = Queue.insert (1,([6,5,4],[1,2,3])); - structure Q – Queue; - Q.insert _. - open Queue; - Empty - Q.Empty Structures Structure Queue = struct type ‘a queue = ‘a list * ‘a list exception Empty val empty = (nil, nil) fun insert (x, q) = … fun remove q = … end Keywords struct … end delimit structure Structure x = … binds X to structure Signature Ascription Recall: Signature QUEUE = sig type ‘a queue exception Empty val empty : ‘a queue end Now we ascribe this signature to a structure: Structure Queue :> QUEUE = struct type ‘a queue = ‘a list * ‘a list val empty = (nil, nil) exception Empty … end Signature Ascription Opaque ascription Provides abstract types Structure Queue :> QUEUE = … Transparent ascription A special case of opaque ascription Hides fields but does not make types abstract Structure Queue_E : QUEUE = … SEE Harper, chapters 18-22 for more on modules Data Types A mechanism for declaring a new type and constructors for the new type and patterns for the new type Datatype colour = Red | Blue | Green > Type colour con Red : colour con Blue : colour con Yellow : colour - Red; > Red : colour - fun favourite colour = case colour of Red | Blue -> true | Green -> false;