07. haskell Membership
-
Upload
sebastian-rettig -
Category
Technology
-
view
221 -
download
0
description
Transcript of 07. haskell Membership
Membership
Sebastian Rettig
In Haskell normally you understand a function by readingFunction Name + Parameter Types + Result Type.
In Haskell normally you understand a function by readingFunction Name + Parameter Types + Result Type.
Functional Programming
● No Variables● Functions only, eventually stored in
Modules– Behavior do not change, once defined
– → Function called with same parameter calculates always the same result
● Function definitions (Match Cases)● Recursion (Memory)
Haskell Features
● Pure Functional Programming Language● Lazy Evaluation ● Pattern Matching and Guards● List Comprehension● Type Polymorphism
Static Type System
● type of every expression is known at compile time
– use operation with not compatible types
– → program won't compile
– → saver code
Nice to remember (1)
● Types:– starts with uppercase letter
– e.g.:● Bool● Int● String● [Int]● (Bool, Char)● Integer
Nice to remember (2)
● Typevariables– to define generic types
– e.g.: ● maxList :: [a] -> a● fst :: (a,b) -> a● snd :: (a,b) -> b
– Typevariables a and b can contain every type (including the same type)
Nice to remember (3)● GHCi Commands (Interpreter):
– :t ← returns the function header (type) – :t tail
tail :: [a] -> [a]– :t 2 == 4
2 == 4 :: Bool– :t "HELLO!"
"HELLO!" :: [Char]
– :i ← returns the function definition (interface)– :i tail
tail :: [a] -> [a] -- Defined in GHC.List
Nice to remember (4)
Typeclasses:● define properties of the types
● like an interface
– Eq can be compared
– Ord can be ordered (>, <, >=, <=) (extending Eq)
– Show can be shown as string
– Read opposite of Show
– Enum sequentially ordered types (can be enumerated
and usable in List-Ranges ['a'..'e'])
Our own Type (1)● in the last session, we created the following Type:
data Shape = Circle Float Float Float |Rectangle Float Float Float Float
● and created a function to move a Shape:moveLeft :: Shape -> Float -> Shape
moveLeft (Circle x y r) m = (Circle (x-m) y r)
moveLeft (Rectangle x1 y1 x2 y2) m = (Rectangle (x1-m) y1 (x2-m) y2)
Our own Type (2)● → and called it in GHCi and got the following
Exception:
Main> moveLeft (Circle 1 2 3) 2 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 : Static Type System
● type of every expression is known at compile time
– use operation with not compatible types
– → program won't compile
– → saver code
● QUESTION:
Would this Code compile?
Remember : Static Type System
● type of every expression is known at compile time
– use operation with not compatible types
– → program won't compile
– → saver code
● QUESTION:
Would this Code compile?
YES!
Membership of a Typeclass● What happens?
– GHCi want's to print out (String) the result
– the Typeclass Show converts a type to String● → Type must be part of the Typeclass Show
● two ways to solve this:
– inherit from existing implementation of types you use
– implement the specific typeclass functions by yourself
Inherit Membership (1)● in the last session, we used the simple way and derived
the Memberships Show, Eq and Ord from Float Type we are using in our Type:
data Shape = Circle Float Float Float |Rectangle Float Float Float Float deriving (Show, Eq, Ord)
● and we check our new Typeclass memberships with (:i):
data Shape = Circle Float Float Float | Rectangle Float Float Float Float
-- Defined at type.hs:3:6-10instance Eq Shape -- Defined at type.hs:3:91-92instance Ord Shape -- Defined at type.hs:3:95-97instance Show Shape -- Defined at type.hs:3:85-88
Inherit Membership (2)● and we can now use:
maxList :: (Ord a) => [a] -> a
maxList [(Circle 1 2 5), (Circle 2 3 4)]
– returns: Circle 2.0 3.0 4.0
● Ord, Eq & Show implementation of Float works
● BUT: the result is not correct, why?
– Ord, Eq Implementation of Float compares only two values
– the first value, if equal → second, if equal → third
– but we need to compare the third value (radius) only
Implement Membership (1)● to solve this, we have to implement Ord and Eq by our own
● first, we have to find the functions of the typeclass to implement :
:i Eqclass Eq a where(==) :: a -> a -> Bool(/=) :: a -> a -> Bool-- Defined in GHC.Classes
● if we look in prelude.hs, we can see the implementation of these functions
Implement Membership (2)● class keyword defines a new typeclass
class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
x == y = not (x /= y)
x /= y = not (x == y)
● a is the type variable
● we have to implement the membership of Eq for our Type Shape
Implement Membership (3)● instance keyword defines a membership instance
instance Eq Shape where
(Circle _ _ r) == (Circle _ _ r') = r == r'
(Rectangle x1 y1 x2 y2) == (Rectangle x1' y1' x2' y2') = (x1 - x2) == (x1' - x2') && (y1 - y2) == (y1' - y2')
_ == _ = False
● we don't need to implement (/=), why?
Implement Membership (4)● and for the Ord Typeclass:
:i Ordclass Eq a => Ord a wherecompare :: a -> a -> Ordering(<) :: a -> a -> Bool(>=) :: a -> a -> Bool(>) :: a -> a -> Bool(<=) :: a -> a -> Boolmax :: a -> a -> amin :: a -> a -> a-- Defined in GHC.Classes
Implement Membership (5)instance Ord Shape where
a <= b = surface a <= surface b
a >= b = surface a >= surface b
a < b = not (a >= b)
a > b = not (a <= b)
● min, max and compare just use the implemented functions
Type Parameters (1)● parameter for a type constructor to create new type
● e.g.: (Maybe for the World)
data Maybe a = Nothing | Just a
● type Maybe is used with another type, but don't care about the type
● e.g.: ghci> :t Just "Hey"Just "Hey" :: Maybe [Char]
● Question: What is the result of:
– :t Just 6
– :t Nothing
Type Parameters (2)● type parameter can also contain typeclass cntraints
● e.g.: data (Ord a) => Maybe a = Nothing | Just a
● BUT please avoid such design!
– → every function must use this constraints
– → even if the do not ord anything
● → better to set constraints in every function header, where you need the constraint
– max :: (Ord a) => a -> a -> a
Record Syntax● for a better structure of your type
data Car = Car { company :: String
, model :: String
, year :: String
} deriving (Show)
● instead of:
data Car = Car String String String deriving (Show)
Record Syntax (2)● to use in code:
ghci> Car {company="Ford", model="Mustang", year=1967}
● result:Car {company = "Ford", model = "Mustang", year = 1967}
● can also contain type parameters:
data Car a b c = Car { company :: a
, model :: b
, year :: c
} deriving (Show)
Type Synonyms● alias for a defined type
● for better reading and context understanding
● to define Type Synonym, use the type keyword
– type String = [Char]
– type Name = String
– type Phonenumber = String
– type Phonebook = [(Name, Phonenumber)]
● can also contain parameters
– type IntMap v = Map Int v
Sources
[1] Haskell-Tutorial: Learn you a Haskell (http://learnyouahaskell.com/, 2012/03/15)
[2] The Hugs User-Manual (http://cvs.haskell.org/Hugs/pages/hugsman/index.html, 2012/03/15)
[3] The Haskellwiki (http://www.haskell.org/haskellwiki, 2012/03/15)