1 / 19

Standard ML

Standard ML. Data types. Concrete Datatypes. The datatype declaration creates new types These are concrete data types, not abstract Concrete datatypes can be inspected - constructed and taken apart ML’s datatypes has two kinds of values: atomic and composite

seanna
Download Presentation

Standard ML

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Standard ML Data types

  2. Concrete Datatypes • The datatype declaration creates new types • These are concrete data types, not abstract • Concrete datatypes can be inspected - constructed and taken apart • ML’s datatypes has two kinds of values:atomic and composite • The only operations supported: • Use atomic values • Construct a composite value • Take a composite value apart: pattern matching

  3. Enumeration Types • Simplest example: single valued type datatype single = only; - only; val it = only : single • only denotes the only value in the type single • Isomorphic to unit • Consisting of a finite number of constants - datatype bool = true | false; datatype bool = false | true - true; val it = true : bool - false; val it = false : bool Read: false or true

  4. Enumeration Types • No order on the elements (unlike Pascal, C) - datatype piece = king | queen | rook | bishop | knight | pawn; datatype piece = bishop | king | knight | pawn | queen | rook - fun value king = Real.posInf (* infinity *) | value queen = 9.0 | value rook = 5.0 | value (bishop | knight) = 3.0 | value pawn = 1.0; val value = fn : piece -> real - value bishop; val it = 3.0 : int

  5. Branding • Newton’s second law: - fun a m f = m/f;val a = fn : real -> real -> real - val (body, engine) = (0.0122, 50.0); - a engine body; (* oops *) val it = 4098.36065574 : real • Type alias will not suffice here type mass = real and force = realand acceleration = real; - fun a (m:mass) (f:force) : acceleration = m/f; val a = fn : mass -> force -> acceleration - a engine body; (* still oops *) val it = 4098.36065574 :acceleration

  6. Constructors • Simulate branding using datatype: datatype mass = Kg of real; datatype force = Newton of real; datatype acceleration = m_s'2 of real; • Constructors are functions - Kg; val it = fn : real -> mass - Newton; val it = fn : real -> force - val body = Kg 0.0122; val engine = Newton 50.0; val body = Kg 0.0122 : massval engine = Newton 50.0 : force • May be passed to other functions - map Kg [1.2, 5.3];

  7. Constructors • Simulate branding using datatype: datatype mass = Kg of real; datatype force = Newton of real; datatype acceleration = m_s'2 of real; • Constructor names are the building blocks of patterns - fun a (Kg m) (Newton f) = m_s'2 (m / f); val a = fn : mass -> force -> acceleration - a body engine; val it = m_s'2 25.0 : acceleration - a engine body; Error: operator and operand don't agree [tycon mismatch] operator domain: mass operand: force in expression:

  8. Variant Types • We’ve already seen an example: enumerated types • Shapes datatype shape = point | Line of real | Circle of real | Rectangle of real*real; • A tagged union • Calculate area: fun area (point | Line _) = 0.0 | area (Circle r) = Math.pi*r*r | area (Rectangle (w, h)) = w * h; val area = fn : shape -> real

  9. Pattern Matching • In val binding:val line = Line 5.3;- valLine length = line; val length = 5.3 : real - valCircle radius = line; uncaught exception Bind [nonexhaustive binding failure] - val (Circle r | Line r) = line; (* both “r”! *) val r = 5.3 : real • What will happen for the following: - valpoint = point; - valpoint = 5.3; val declaration fails if the matching fails (* OK. *) (* FAIL - types mismatch *) Constructors cannot be rebound in a binding declaration

  10. Recursive Datatypes • Let’s recall the definition of lists: • “Every list is either nilor has the form x::xs where x is its head and the list xs is its tail.” • We can do it ourselves! datatypeintlist = nil | :: of int * intlist; • What if we omit the “nil” part in the datatype definition? • Defining functions – as usual: - fun length nil = 0 | length (_::xs) = 1 + length xs; • We can’t have the [] syntax. That’s a built-in syntactic sugar

  11. Recursive Datatypes • Recursive data type without a pointer? How can it be? • Note that :: is actually a function, so we have an indirection • Datatypes can be mutually recursive • Again, using “and”, just like in declarations: datatypedecl = Val of string * expr | Local ofdecl * decl andexpr = Literal | Fn ofexpr * expr | Let of decl * expr; datatype decl = Local of decl * decl | Val of expr datatype expr = Fn of expr * expr | Let of decl * expr | Literal

  12. Recursive Datatypes Polymorphic Datatypes • “intlist”? Seriously? What’s so special about ints? • Well, nothing, of course. Guess what comes next? datatype 'a list = nil | :: of 'a * ('a list); - "hello" :: "world" :: nil; val it = "hello" :: "world" :: nil : string list • In OOP terminology, it is called “generics”

  13. Polymorphic Datatypes • Simplest polymorphic type – abstract the idea of branding datatype 'a tagged = tag of 'a; • Two things are declared here: • the type operatortag • the constructor tag : fn 'a -> 'a tagged • Note that this is less informative the manual branding • We can denote optional parameters in function: datatype 'a option = NONE | SOME of 'a; • We can use datatypes to “unite” two different types. We can abstract on this idea, and create a datatype uniting any two types: ‘a and ‘b datatype ('a,'b) union = type1 of 'a | type2 of 'b; • Example – in the next slide

  14. Union - Example datatype ('a,'b) union = type1 of 'a | type2 of 'b; • val five = type1 5; val five = type1 5 : (int,'a) union • val hello = type2 "hello"; val hello = type2 "hello" : ('a,string) union - valfive_or_hello = if true then five else hello; val five_or_hello = type1 5 : (int,string) union

  15. Trees datatype 'a tree = Nil | Br of 'a * ('a tree) * ('a tree); fun Leaf x = Br (x, Nil, Nil); - val tree2 = Br(2, Leaf 1, Leaf 3); val tree2 = Br (2,Br (1,Nil,Nil),Br (3,Nil,Nil)) : int tree - val tree5 = Br(5, Leaf 6, Leaf 7); - val tree4 = Br(4, tree2, tree5); val tree4 = Br (4,Br (2,Br #,Br #),Br (5,Br #,Br #)) : int tree - fun size Nil = 0 | size (Br (v,t1,t2)) = 1 + size t1 + size t2; val count = fn : ‘a tree -> int

  16. Binary Search Trees • Implement an associative array using trees • The tree will be of type (int * 'a) tree • int is the key, since ML does not have “ordered type” interface • Value may be anything • Assumption: The tree is sorted • Any key on the left subtree is smaller than the current key • The current key is larger than any of the keys in the right subtree • We will define two functions: • insert = fn : (int * 'a) tree -> int * 'a -> (int * 'a) tree • get = fn : (int * 'a) tree -> int -> 'a • Two helpers: • datatype order = LESS | EQUAL | GREATER (* predefined *) • val compare : int*int->order= Int.compare

  17. Binary Search Trees fun get (Br ((node_k, v), left, right)) k = case compare (node_k, k) ofEQUAL => v | GREATER => get right k | LESS => get left k; local fun compare (k1,_) (k2,_) = compare (k1, k2) in funinsertNil item = Br (item, Nil, Nil) | insert (Br (node, left, right)) item = case cmp node item of EQUAL => Br (item, left, right) | GREATER => Br (node, left, insert right item) | LESS => Br (node, insert left item, right) end

  18. Binary Search Trees • “Continuation passing” : tail recursion elimination localfun cmp (k1,_) (k2,_) = compare (k1-k2) in funinsertNil item seal = seal (Br (item, Nil, Nil)) | insert (Br (node, left, right)) item seal = case cmp node item of EQUAL => seal (Br (item, left, right)) | GREATER => insert right item (fn t => seal (Br (node, left, t))) | LESS => insert left item (fn t => seal (Br (node, t, right))) end

  19. Vague Summary Concrete Polymorphic Atomic Composite “full” Recursive Enumeration Inhabitable + recursive Mutually Recursive

More Related