1. Membership
Sebastian Rettig
In Haskell normally you understand aa function by reading
In Haskell normally you understand function by reading
Function Name ++ Parameter Types + Result Type.
Function Name Parameter Types + Result Type.
2. 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)
3. Haskell Features
● Pure Functional Programming Language
● Lazy Evaluation
● Pattern Matching and Guards
● List Comprehension
● Type Polymorphism
4. Static Type System
● type of every expression is known at
compile time
– use operation with not compatible types
– → program won't compile
– → saver code
5. Nice to remember (1)
● Types:
– starts with uppercase letter
– e.g.:
● Bool
● Int
● String
● [Int]
● (Bool, Char)
● Integer
6. 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)
7. 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
8. 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'])
9. 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)
10. 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
11. 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?
12. 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!
13. 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
14. 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-10
instance Eq Shape -- Defined at type.hs:3:91-92
instance Ord Shape -- Defined at type.hs:3:95-97
instance Show Shape -- Defined at type.hs:3:85-88
15. 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
16. 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 Eq
class 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
17. 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
19. Implement Membership (4)
● and for the Ord Typeclass:
:i Ord
class Eq a => Ord a where
compare :: a -> a -> Ordering
(<) :: a -> a -> Bool
(>=) :: a -> a -> Bool
(>) :: a -> a -> Bool
(<=) :: a -> a -> Bool
max :: a -> a -> a
min :: a -> a -> a
-- Defined in GHC.Classes
20. 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
21. 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
22. 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
23. 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)
24. 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)
25. 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
26. 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)