# 06. haskell type builder

Post on 16-Apr-2017

356 views

Embed Size (px)

TRANSCRIPT

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

Recommended