Download presentation
Presentation is loading. Please wait.
1
Type Definitions cs776 (prasad) L8tdef
2
Concrete Types Primitive types ( int, bool, char, string, etc ) Type constructors ( ->, list, etc ) Real world concepts can be modeled better with concrete types rather than simulated using primitive types. datatype decision = (yes,no,maybe); Readability (self-documenting) Reliability (automatic detection of errors) operations on values of a type are independent of the operations on their representations. Certain errors cannot be mechanically detected if directions are simulated using integers. Encoding of days of a week as numbers spelt out in comments in the absence of concrete types. Guard against addition of days of a week…. (Enumerated/Scalar types) cs776 (prasad) L8tdef
3
Language Aspects Naming the new type Constructing values of the type
Inspecting values and testing their type for defining functions Canonical representation (for equality tests) In ML, one can use symbolic terms to construct values in a type, and use patterns to define functions on this type. cs776 (prasad) L8tdef
4
Introducing Type Names
type pair = int * int; type points = int list; Type Equivalence Structural Equivalence - val x = (1,2) : pair; - (1,1) : int * int; - x = (1,1); (* val it = false : bool *) Cf. C++ typedef cs776 (prasad) L8tdef
5
Enumerated types with constants
datatype directions = North | South | East | West ; fun reverse North = South | reverse South = North | reverse East = West | reverse West = East ; val reverse = fn : directions -> directions fun isEast x = (x = East); In contrast with Pascal and Ada, relational operations such as “<“ are not defined on enumerated types. (very restricted overloads) The type contains a finite set of values. datatype mine = a | false; // legal true : boolean; // bool constants are not reserved. false : mine; // predefined constant got redefined!! cs776 (prasad) L8tdef
6
Constructors with Arguments
datatype phy_quant = Pressure of real | Volume of real ; datatype position = Coord of int * int; (Tagged values) (Cf. Ada Derived Types) Recursive Types datatype number = Zero | Succ of number; datatype tree = leaf of int | node of (tree*int*tree); E.g., node (leaf 25,10,leaf 20) : tree; Similarly, tagging with units (centigrade, farenheit, absolute, …), or with their logical role. Language provides mechanisms to make explicit programmer intent, to enable mechanical checking for reliability. Primitive type : Finite type : Built on infinite primitive type : New infinite type cs776 (prasad) L8tdef
7
Defining Functions fun add (Zero, n) = n
| add (Succ(m),n) = Succ(add(m,n)); val add = fn : number * number -> number fun mul (Zero, n) = Zero | mul (Succ(m),n) = add(n,mul(m,n)); val mul = fn : number * number -> number mul ( Succ(Succ Zero), Succ Zero ) = Succ(Succ Zero); (* Expression evaluation - Normalization *) Structural induction : completeness in the definition cs776 (prasad) L8tdef
8
New Type Operators datatype ’e matrix = Matrix of (’e list list);
datatype 'a matrix = Matrix of 'a list list datatype ’a list = nil | :: of (’a * ’a list); datatype 'a list = :: of 'a * 'a list | nil (* Using ‘a instead of ’a generates errors. *) (* Using [] instead of nil generates an error. *) Beware of errors in patterns containing symbolic terms 1. A typo in constructor name may lead to an interpretation of a catch-all variable. 2. A missing blank separator between a unary constructor and its argument (possibly wild card) may be misinterpreted as a variable name. 3. Ambiguity in dangling case clauses for nested cases can be resolved using parenthesis. 4. Sometimes compiler warnings such as “unreachable clauses” or “incomplete matches” may flag such problems. cs776 (prasad) L8tdef
9
Semantics of Concrete Types
Algebra = (Values, Operations) E.g, vector/matrix algebra, group theory, etc. Free Algebra Construction is a way of defining an algebra from a collection of CONSTRUCTORS using SIGNATURE information. E.g., datatype t = e | u of t | p of t*t; cs776 (prasad) L8tdef
10
What are the values in the type? What are the operations on the type?
datatype t = e | u of t | p of t*t; Signatures e : t u : t -> t p : t*t -> t What are the values in the type? What are the operations on the type? cs776 (prasad) L8tdef
11
Values e u(e), p(e,e) u(u(e)), u(p(e,e)),
p(e,u(e)), p(e,p(e,e)), p(u(e),e), p(p(e,e),e), … . . . (* Unique name hypothesis *) Grammar V := e | u(V) | p(V,V) cs776 (prasad) L8tdef
12
Operations u (“function from terms to terms”)
e ~> u(e) u(e) ~> u(u(e)) … p (“function from terms*terms to terms”) e, e ~> p(e,e) u(e),e ~> p(u(e),e) p(e,e),e ~> p(p(e,e),e) Semantics of t ({e,u(e),p(e,e),…}, {u,p}) cs776 (prasad) L8tdef
13
Specification and Implementation through Examples
Abstract Type Specification and Implementation through Examples Not equality types. cs776 (prasad) L8tdef
14
Integer Sets: Algebraic specification
empty : intset insert : intset -> int -> intset remove : intset -> int -> intset member : intset -> int -> bool for all s e intset, m,n e int: member empty n = false member (insert s m) n = (n=m) orelse (member s n) remove empty n = empty remove (insert s m) n = if (n=m) then remove s n else insert (remove s n) m Multiple Implementations: 1. Same representation different data invariants a. multiplicity allowed, unordered b. single entries, unordered. c. single entries, ordered 2. Different representation : function … (Finite (limited vs unbound) vs infinite sets) 3. Type parameterization cs776 (prasad) L8tdef
15
intset = Empty | Insert of intset*int with val empty = Empty
abstype intset = Empty | Insert of intset*int with val empty = Empty fun insert s n = Insert(s,n) fun member Empty n = false | member (Insert(s,m)) n = (n=m) orelse (member s n) fun remove Empty n = Empty | remove (Insert(s,m)) n = if (n=m) then remove s n else Insert(remove s n, m) end; Literal translation of the ADT spec. Representation in terms of term trees. Uninterpreted symbols. (Duplication present - Unordered.) Generalizable to equality types. type intset val empty = - : intset val insert = fn : intset -> int -> intset val member = fn : intset -> int -> bool val remove = fn : intset -> int -> intset Difference between algebraic spec and the abstype definition is in the definition of equality. In the former, we can write equations, in the latter, we need to give a constructive definition of “same”. cs776 (prasad) L8tdef
16
val s1 = (insert empty 5); val s2 = (insert s1 3);
(member s1 8); (member s1 5); (member s1 1); val s3 = (remove s1 5); (member s3 5); No side-effects cs776 (prasad) L8tdef
17
abstype intset = Set of int list with val empty = Set [] fun insert (Set s) n = Set(n::s) fun member (Set s) n = List.exists (fn i => (i=n)) s fun remove (Set s) n = Set (List.filter (fn i => (i=n)) s) end; (* member and remove are not primitives in structure List because they are defined only for equality types. *) Other implementations : sort the list, remove duplicates (representations satisfy additional properties : invariants) cs776 (prasad) L8tdef
18
intset = Set of (int -> bool) with val empty =
abstype intset = Set of (int -> bool) with val empty = Set (fn n => false) fun insert (Set s) n = Set (fn m => (m = n) orelse (s m)) fun member (Set s) n = (s n) fun remove (Set s) n = Set (fn m => (not(m = n)) andalso (s m)) end; Unorthodox impl. in terms of functions “infinite” sets can be described but cannot check for empty set! cs776 (prasad) L8tdef
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.