160 likes | 303 Views
Defining new types of data. Defining New Datatypes. Ability to add new datatypes in a programming language is important. Kinds of datatypes enumerated types records (or products or struct) variant records (or sums) pointer types arrays
E N D
Defining New Datatypes • Ability to add new datatypes in a programming language is important. • Kinds of datatypes • enumerated types • records (or products or struct) • variant records (or sums) • pointer types • arrays • Haskell’s data declaration provides many of these kinds of types in a uniform way which abstracts from their implementation details. • The datadeclaration defines new functions and constants, which provide an abstract interface to the newly defined type.
The Data Declaration • Enumeration Types data Day = Sun | Mon | Tue | Wed | Thu | Fri | Sat deriving Eq • The names on right hand side are constructor constants and are the onlyelements of the type.
Other enumeration data types we already know • data Ordering = Eq | LT | GT • data Bool = True | False
Writing functions (1) • Functions written by mult-clause definitions dayOfWeek:: Day -> Int dayOfWeek Sun = 1 dayOfWeek Mon = 2 dayOfWeek Tue = 3 dyaOfWeek Wed = 4 dayOfWeek Thu = 5 dayOfWeek Fri = 6 dayOfWeek Sat = 7 ? dayOfWeekThu 5 :: Int
Writing functions (2) • Functions written by using the case expression dayOfWeek:: Day -> Int dayOfWeek x = case x of Sun -> 1 Mon -> 2 Tue -> 3 Wed -> 4 Thu -> 5 Fri -> 6 Sat -> 7
Constructors with arguments(sometimes called sums or variants) data [a] = [] | (:) a [a] data Tree a = Tip | Fork (Tree a) a (Tree a)
Constructors & Patterns • data defined types define new constructors and can be accessed by patterns. • Constructors without arguments are constants • Example using case dayOfWeekx = case x of Sun -> 0 Mon -> 1 Tue -> 2 Wed -> 3 ; Thu -> 4 ; Fri -> 5 Sat -> 6 • Note: Indentation bounds each clause ( pat -> body) in case, or use a semi-colon rather than indentation.
Patterns in Declarations • In a declaration patterns can be used. Possible to have many lines for a definition if each pattern is distinct. dayOfWeekSun = 0 dayOfWeekMon = 1 dayOfWeekTue = 2 dayOfWeekWed = 3 dayOfWeekThu = 4 dayOfWeekFri = 5 dayOfWeekSat = 6 ? dayOfWeekTue 2
Patterns with variables • If the constructors aren’t constants then patterns have variables len[] = 0 len (x:xs) = 1 + lenxs depth Tip = 0 depth (Forkxay) = 1 + max (depth x) (depth y)
Patterns in case expressions • One can use patterns in case expressions as well as in multi-clause defintions len x = case x of [] -> 0 (x : xs) -> 1 + lenxs depth x = case x of Tip -> 0 (Fork xay) -> 1 + max (depth x) (depth y) Note use of indentation
Rules for patterns • When writing functions (using multi clause functions or case expressions) there is always 1 case for each of the construtors. • Patterns always have constructors and variables. • Constructors start with a capital letter • Exceptions [] and cons (:) which are special syntax for lists, and (x,y,z) which is special syntax for tuples. • [x,y,z] syntax can also be used for lists of fixed length! • Constants don’t have variables • Constructors with args must always have the correct number • Patterns can be nested • (Fork Tip x Tip) • [(x,y,z)]
Other Enumeration Examples data Move = Paper | Rock | Scissors beats :: Move -> Move beats Paper = Scissors beats Rock = Paper beats Scissors = Rock ? beats Paper Scissors data Bool = True | False data Direction = North | East | South | West
More about Variant Records • More complicated types data Tagger = Tagn Int | Tagb Bool • NOTE: the types of the constructors are functions (not constants as for enumerated types) Tagb :: Bool -> Tagger Tagn :: Int -> Tagger • As for all constructors: (Tagn 12) • 1) Cannot be simplified. We say it is Canonical • 2) Can be used in a pattern on the left hand side of an =
Example functions on Tagger number (Tagn n) = n boolean (Tagb b) = b isNum (Tagn _) = True isNum (Tagb _) = False ? :t number number :: Tagger -> Int ? number (Tagn 3) 3 ? isNum (Tagb False) False
Another Variant Record-like Type data Temp = Celsius Float | Fahrenheit Float | Kelvin Float • Use patterns to define functions over this type: toKelvin (Celsius c) = Kelvin(c + 273.0) toKelvin (Fahrenheit f) = Kelvin( (f - 32.0) * (5.0/9.0) + 273.0 ) toKelvin (Kelvin k) = Kelvin k Note: 3 constructors means 3 clauses