20-CS-4003-001 Organization of Programming Languages Fall 2018
Types

Lambda calculus, Type theory, Formal semantics, Program analysis

Prev     Next     All lectures           Code

The Type System

 ```{- data Bool = True | False deriving (Show) -} {- data Maybe a = Nothing | Just a deriving (Show) -} data Color = Red | Green | Blue | Indigo | Violet deriving (Ord, Eq, Show) data Point a = Pt a a data Tree a = Empty | Node a (Tree a) (Tree a) | Leaf a deriving (Show, Read, Eq) data Either a b = Left a | Right b deriving (Eq, Ord, Read, Show) data Shape = Circle Float Float Float | Rectangle Float Float Float Float | Triangle Int Int area (Circle x y r) = pi*r^2 area (Rectangle x y w h) = w*h area (Triangle b h) = (fromIntegral b)*(fromIntegral h)/2 v1 = area (Circle 3 4 5) v2 = area (Rectangle 1 2 3 4) v3 = area (Triangle 5 7) v4 = Just "a string" v5 x y = Just x+y v6 = Main.Right 'a' treeInsert x Empty = Leaf x treeInsert x (Leaf a) | x == a = Leaf x | x < a = Node a (treeInsert x Empty) Empty | x > a = Node a Empty (treeInsert x Empty) treeInsert x (Node a left right) | x == a = Node x left right | x < a = Node a (treeInsert x left) right | x > a = Node a left (treeInsert x right) inTree x EmptyTree = False inTree x (Leaf a) | x == a = True | otherwise = False inTree x (Node a left right) | x == a = True | x < a = inTree x left | x > a = inTree x right v7 = treeInsert Green Empty v8 = treeInsert Indigo v7 v9 = treeInsert Blue v8 v10 = treeInsert Red v9 v11 = treeInsert Violet v10 v12 = inTree Violet v11 v13 = inTree Violet v10 ``` - Haskell's type system has been engineered to be both flexible, as a logic for property verification, and powerful. Haskell's type system has been developed to encourage a relatively flexible, expressive static checking discipline, that enable powerful new classes of compile-time verification. Haskell/GHC provides a logic that is both powerful and designed to encourage type level programming. See the haskell review for a list of built-in data types and type classes. Users may define types according to the following syntax: ``` data T u1 ... un = C1 t1,1 ... t1,k1 | ... | Cn tn,1 ... tn,kn ``` where   T is a type constructor   ui are type variables   Ci are data constructors   ti,j are constituent types The presence of ui imply the type is polymorphic (it may be instantiated by substituting different types for ui). Simple examples are shown at the top to the left. Bool and Color are nullary type constructors because they have no arguments. Bool redefines an existing data type which is OK except that using True or False will be ambiguous unless the type used is specified, for example with Main.True. True, False, Red, etc are nullary data constructors. Bool and Color are enumerations because all of their data constructors are nullary. Color objects may be compared due to the deriving (Ord, Eq) extension to the type definition. Thus: ``` *Main> Red < Green True *Main> Violet < Blue False *Main> Indigo == Indigo True ``` Point is a product or tuple type constructor because it has only one constructor. Tree is a union of types, often called an algebraic data type. Maybe will be important to support polymorphism. Consider the Shape type which is the union of a Circle type, defined by a 2-D coordinate center plus radius, a Rectangle type, defined by an upper left 2-D coordinate corner plus width and height, and a Triangle type defined by a base and height. Observe that the constructors Circle and Rectangle take Float arguments and the the Triangle constructor takes Int arguments. Do this: ``` *Main> :t Circle Circle :: Float -> Float -> Float -> Shape *Main> :t Triangle Triangle :: Int -> Int -> Shape ``` The function area, to the left, is defined for all shapes. ``` *Main> v1 78.53982 *Main> v2 12.0 *Main> v3 17.5 ``` Due to the type variable in the type constructor Maybe, Main.Just is the polymorphic type a -> Main.Maybe a. Since Maybe is redefined here, Main.Just must be used because Just is defined in Prelude and the prefix Main. is necessary to prevent ambiguity. ``` *Main> v4 Just "a string" *Main> :t v4 v4 :: Maybe [Char] *Main> :t v5 v5::Num (Maybe a) => a -> Maybe a -> Maybe a ``` Without deriving (Show) in the definition of Maybe we would get: ``` No instance for (Show (Main.Maybe [Char])) arising from a use of print' ``` Similarly, ``` *Main> Main.Right 'a' v6 :: Main.Either a Char ``` when trying to display the value of v4. The functions treeInsert and inTree build a binary search tree and conduct a search for an element in a binary search tree, respectively, based on a recursive binary search tree data type called Tree. The type of treeInsert is ``` treeInsert :: Ord a => a -> Tree a -> Tree a ``` Therefore, Nodes can be Colors, Integers and other types in the class Ord. ``` *Main> v7 Leaf Green *Main> v8 Node Green Empty (Leaf Indigo) *Main> v9 Node Green Empty (Node Indigo (Leaf Blue) Empty) *Main> v10 Node Green (Leaf Red) (Node Indigo (Leaf Blue) Empty) *Main> v11 Node Green (Leaf Red) (Node Indigo (Leaf Blue) (Leaf Violet)) *Main> v12 True *Main> v13 False ```