# Haskell Chapter 7. Topics  Defining data types  Exporting types  Type parameters  Derived instances  Type synonyms  Either  Type classes  Not.

## Presentation on theme: "Haskell Chapter 7. Topics  Defining data types  Exporting types  Type parameters  Derived instances  Type synonyms  Either  Type classes  Not."— Presentation transcript:

Topics  Defining data types  Exporting types  Type parameters  Derived instances  Type synonyms  Either  Type classes  Not covered  record syntax  recursive data structures  subclassing  parameterized types as instances of type classes  Yes-No type class (emulate JavaScript-like behavior)  Functor type class

Define a new data type data Bool = False | True  data keyword indicates a new data type (Bool is not new, just an example)  False and True are value constructors  | is “or” – Bool can be False or True  Type name and value constructors must start with capital letter  Value constructors are actually functions that return a value of a data type

Shape example -- Circle parms coordinates and radius -- Rectangle parms upper left and lower right coordinates data Shape = Circle Float Float Float | Rectangle Float Float Float Float  *Main> :t Circle  Circle :: Float -> Float -> Float -> Shape  *Main> :t Rectangle  Rectangle :: Float -> Float -> Float -> Float -> Shape

Shape continued area :: Shape -> Float area (Circle _ _ r) = pi * r ^2 area (Rectangle x1 y1 x2 y2) = (abs \$ x2 - x1) * (abs y2 - y1)  Notice the pattern match against constructor  *Main> let c = Circle 3 4 5  *Main> area c  78.53982  But we don’t know how to show a circle (yet)  *Main> c  :15:1:  No instance for (Show Shape)  arising from a use of `print'  Possible fix: add an instance declaration for (Show Shape)  In a stmt of an interactive GHCi command: print it remember \$ is function application

Updating shape to be displayed data Shape = Circle Float Float Float | Rectangle Float Float Float Float deriving (Show)  *Main> let c = Circle 3 4 5  *Main> c  Circle 3.0 4.0 5.0

Improving Shape with a Point data type data Point = Point Float Float deriving (Show) data Shape = Circle Point Float | Rectangle Point Point deriving (Show) area :: Shape -> Float area (Circle _ r) = pi * r ^2 area (Rectangle (Point x1 y1) (Point x2 y2)) = (abs \$ x2 - x1) * (abs y2 - y1)  *Main> area (Rectangle (Point 0 0) (Point 100 100))  10000.0

Another method for Shapes nudge :: Shape -> Float -> Float -> Shape nudge (Circle (Point x y) r) dx dy = Circle (Point (x+dx) (y+dy)) r nudge (Rectangle (Point x1 y1) (Point x2 y2)) dx dy = Rectangle (Point (x1+dx) (y1+dy)) (Point (x2+dx) (y2+dy))  *Main> nudge (Circle (Point 34 34) 10) 5 10  Circle (Point 39.0 44.0) 10.0

Exporting shape module Shapes ( Point(..), Shape(..), area, nudge ) where  Shape(..) exports all value constructors (in this case Circle and Rectangle).  Makes it easy to add more shapes later (OCP)  If just export Shape, not Shape(..), can’t pattern match (Programming Languages: support for encapsulation)

Type Parameters  A value constructors takes some parameters, produces a new value (e.g., Circle takes 3 values, returns a circle value)  A type constructor takes a type as a parameter, returns a new type  Maybe type constructor defined as: data Maybe a = Nothing | Just a  Can’t have just Maybe… needs to be Maybe something  Why is this useful? Strong typing. In Java, a function might return a Point or null. This is not possible in Haskell. So if a function may or may not produce a value, then the return type is Maybe something (e.g., Maybe Point)

Usage  Due to type inference, often don’t pass parameters to type constructors explicitly  If a value is Just ‘a’, Haskell infers type as Maybe Char  Concrete type either doesn’t take any type parameters, e.g., Int, Bool OR has filled type parameters (Maybe Char)  List type takes a parameter, returns concrete type  [Int] is an example

Play with it  *Main> Just "Haha"  Just "Haha"  *Main> Just 84  Just 84  *Main> :t Just "Haha"  Just "Haha" :: Maybe [Char]  *Main> :t Just 84  Just 84 :: Num a => Maybe a  *Main> :t Nothing  Nothing :: Maybe a  *Main> Just 10 :: Maybe Double  Just 10.0

Type class \= Java class  In Java, we use a class as a blueprint to create objects  In Haskell, you use type classes to make a data type, then think about how it can act  We do this with deriving  If types of all fields are part of a type class, then our new type can be part of a type class data Person = Person { name :: String, age :: Int } deriving (Eq, Show)

Example  *Shapes> let frodo = Person {name = "Frodo Baggins", age = 43}  *Shapes> let bilbo = Person {name = "Bilbo Baggins", age = 100}  *Shapes> bilbo  Person {name = "Bilbo Baggins", age = 100}  *Shapes> bilbo == frodo  False  *Shapes> let imposter = Person {name = "Frodo Baggins", age = 43}  *Shapes> frodo == imposter  True

Enum example data Day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday deriving (Eq, Show, Ord, Read, Bounded, Enum) *Chap7> Wednesday Wednesday *Chap7> show Wednesday "Wednesday" *Chap7> read "Saturday" :: Day Saturday *Chap7> Saturday == Sunday False *Chap7> Monday `compare` Wednesday LT *Chap7> Saturday > Friday True *Chap7> minBound :: Day Monday *Chap7> maxBound :: Day Sunday *Chap7> let weekend = [Friday.. Sunday] *Chap7> weekend [Friday,Saturday,Sunday]

Type Synonyms  [Char] and String are type synonyms type PhoneNumber = String type Name = String type PhoneBook = [(Name, PhoneNumber)] inPhoneBook :: Name -> PhoneNumber -> PhoneBook -> Bool inPhoneBook name pnumber pbook = (name, pnumber) `elem` pbook Not covered: parameterized type synonyms

Could be Either  Use to encapsulate a value of one type or another  Is defined as:  data Either a b = Left a | Right b deriving (Eq, Ord, Read, Show)  *Chap7> Right 20  Right 20  *Chap7> Left "Whoa"  Left "Whoa"  *Chap7> :t Right 'a'  Right 'a' :: Either a Char  *Chap7> :t Left True  Left True :: Either Bool b

Either with try  The try functions  try :: Exception e => IO a -> IO (Either e a)SourceExceptionIO EitherSource  Similar to catch, but returns an Either result which is (Right a) if no exception of type e was raised, or (Left ex) if an exception of type e was raised and its value is ex. If any other type of exception is raised than it will be propogated up to the next enclosing exception handler.catchEitherRightLeft  try a = catch (Right `liftM` a) (return. Left) http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Control-Exception.html#7

Usage  Maybe can be used if function might return a result or fail  Either can be used if there are multiple possible results  You’ll explore this more in the homework

Type Classes 102  Type classes are sort of like interfaces: they define behavior  Types that can behave that way are made instances (just means they can use the functions associated with that type class) class Eq a where (==) :: a -> a -> Bool (/=) :: a -> a -> Bool x == y = not (x /= y) x /= y = not (x == y) note the mutual recursion… only need to implement one!

Using a type class data TrafficLight = Red | Yellow | Green instance Eq TrafficLight where Red == Red = True Green == Green = True Yellow == Yellow = True _ == _ = False instance Show TrafficLight where show Red = "Red Light" show Green = "Green Light" show Yellow = "Yellow Light"

Using the Traffic Light  *Chap7> Red  Red Light  *Chap7> Red  Red Light  *Chap7> Red == Red  True  *Chap7> Red == Green  False  *Chap7> Red `elem` [Red, Green, Yellow]  True

Similar presentations