Download - 06. haskell type builder
Keyboard
Type-Builder
Sebastian Rettig
In Haskell normally you understand a function by readingFunction Name + Parameter Types + Result Type.
Functional Programming
No Variables
Functions only, eventually stored in ModulesBehavior 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 timeuse 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)
Typevariablesto 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
Type Polymorphism (1)
Statically typed, but Compiler can read type from context (type inference)
no need to set type explicitly (but preferred!)
makes function more generic for different kinds of types (type polymorphism)Why should I use quicksort :: [Int] -> [Int]
even if I also want to sort character?Hugs> quicksort ['f','a','d','b'] "abdf"
Type Polymorphism (2)
the header could befact :: Int -> IntmaxList :: [Int] -> Int
but is only limited to Int, but maxList could also handle Char
why not make it generic?maxList :: [a] -> a
but what happens, if the corresponding Type is not comparable or cannot be ordered?
Type Polymorphism (3)
Solution: use TypeclassesmaxList :: (Ord a) => [a] -> a
then we can be sure to use ()
function header can contain multiple typeclassesmaxList :: (Ord a, Eq b) => [a] -> [b] -> a
In Haskell-Interpreter: to list the function header:t
Typeclasses (1)
define properties of the types
like an interface
Typeclasses: Eq can be compared
Ord can be ordered (>, =, Float -> Float -> Shape
to look at the Type definition , you can use: :i Shape
Question: What is the result of: :t Red in
data TrafficLight = Red | Yellow | Green?
Let's use our type
e.g.: calculate the surface of a Shapesurface :: Shape ->
Floatsurface (Circle _ _ r) = pi * r ^ 2surface (Rectangle x1 y1 x2
y2) =
(abs $ x2 - x1) * (abs $ y2 - y1)
and call it:
Main> surface (Circle 1 2 3)
28.274334
sometimes the parenthesis are annoying better readability with $ surface $ Circle 1 2 3
Type Handling
Why not just use (Float, Float, Float)? can define everything (e.g.: vector) no context
needs two functions, one for Circle and one for Rectangle
in Haskell normally you understand a function by readingfunction name + parameter types + result type
you should write explicitly the function header
except for really small functions
Another Function
e.g.: move left a ShapemoveLeft :: Shape -> Float -> ShapemoveLeft (Circle x y r) m = (Circle (x-m) y r)moveLeft (Rectangle x1 y1 x2 y2) m = (Rectangle (x1-m) y1 (x2-m) y2)
and call it:
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
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)
If used types are already member of the TypeclassHaskell use the implementation of this types to print the specific values
Value Constructor can generally be printed out
you only need to derive from the Implementation
Inherit Membership (2)
first check if Float has already a membership:data Float =
GHC.Types.F# GHC.Prim.Float# -- Defined in GHC.Types
instance Show Float -- Defined in GHC.Float
okay, then we can use the deriving keyworddata Shape =
Circle Float Float Float |
Rectangle Float Float Float Float
deriving (Show)
and call again: moveLeft (Circle 1 2 3) 2
Circle (-1.0) 2.0 3.0
Inherit Membership (3)
Float has also membership of Typeclass Ord:instance Ord Float -- Defined in GHC.Classesinstance Eq Float -- Defined in GHC.Classes
we can also derive from Ord but also from Eqdata Shape =
Circle Float Float Float |
Rectangle Float Float Float Float
deriving (Show, Eq, Ord)
and we can use: maxList :: (Ord a) => [a] -> a
maxList [(Circle 1 2 3), (Circle 2 3 4)]returns: Circle 2.0 3.0
4.0
Inherit Membership (4)
to check our new Typeclass memberships: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
Implement Membership
Next Session :)
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)
Click to edit the title text format