02. haskell motivation

Post on 11-May-2015

401 Views

Category:

Education

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

Haskell Meetup Session 2

TRANSCRIPT

Motivation

Sebastian Rettig

“Recursion is important to Haskell because unlike imperative languages, you do computations in Haskell by declaring what something is instead of declaring how you get it.” ([1])

“Recursion is important to Haskell because unlike imperative languages, you do computations in Haskell by declaring what something is instead of declaring how you get it.” ([1])

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

When you start...

● You want to do big projects with Haskell?

● Then start simple, because:

– a function is Simple and...

Simple Simple Simple Simple

Simple Simple

Simple Simple

Simple

SimpleAbstraction- Level

BIGProject

Let's start simple● You need a Framework to start with Haskell?

– then write one, if you really think you need one :)

– but be aware of● Haskell == simple● Framework == should also be simple

● a simple function:

– just ignore the function header at the beginning

countNum 1 = “One”

countNum 2 = “Two”

countNum x = “toooo difficult to count...”

How to implement the Factorial?

● Remember:

“Recursion is important to Haskell because unlike imperative languages, you do computations in Haskell by declaring what something is instead of declaring how you get it.” ([1])

● Okay, then look at the definition:

– Imperative definition

– Recursive definition

Let's look at the imperative way...

● Imperative

function factorial(n) { int result = 1; if (n == 0) return result; } for (int i=1; i<n; i++) { result *= i; } return result;}

● Recursive

…and translate to the functional way

● Imperative

function fact(n) { int result = 1; if (n == 0) return result; } for (int i=1; i<n; i++) { result *= i; } return result;}

● Recursive

fact 0 = 1fact n = n * fact (n-1)

● and in comparison with the definition:

● BUT imperative also possible:

fact' 0 = 1fact' n = product [1..n]

● compared with the definition:

The maximum value of a List?

● Remember:

“Recursion is important to Haskell because unlike imperative languages, you do computations in Haskell by declaring what something is instead of declaring how you get it.” ([1])

● Okay, then look at the definition:

Let's look at the imperative way...

● Imperative

function max(array list) { if (empty(list)) { throw new Exception(); } max = list[0] for (int i=0; i<length(list);

i++) { if (list[i] > max) { max = list[i]; } } return max;}

● Recursive

…and translate to the functional way ● Imperative

function max(array list) { if (empty(list)) { throw new Exception(); } max = list[0] for (int i=0; i<length(list);

i++) { if (list[i] > max) { max = list[i]; } } return max;}

● Recursive

maxList [] = error “empty”maxList [x] = xmaxList (x:xs) | x > maxTail = x | otherwise = maxTail where maxTail = maxList xs

● or simpler:maxList [] = error “empty”maxList [x] = xmaxList (x:xs) = max x (maxList xs)

● and in comparison with the definition:

Types in Haskell (1)

Starts with uppercase first character

● Int bounded from -2147483648 to 2147483647

● Integer unbounded (for big numbers) but slower than Int

● Float floating point (single precision)

● Double floating point (double precision)

● Bool boolean

● Char character

● String list of Char (String == [Char])

Types in Haskell (2)

● Lists: must be homogenous (entries from the same type)

– [] empty List

– [Int] List of Int

– But e.g. [Int, Bool] not allowed (not homogenous)!

● Tuples: can contain different types BUT have fixed length

– () empty tuple (has only 1 value)

– (Int, Bool) tuple of a pair Int, Bool

– (Int, Bool, Bool) tuple of Int, Bool, Bool

List-Functions● head returns first element of list

– head [1,2,3] returns 1

● tail returns list without first element

– tail [1,2,3] returns [2,3]

● init returns list without last element

– init [1,2,3] returns [1,2]

● last returns last element of list

– last [1,2,3] returns 3

Tuple-Functions● fst returns first element of a pair

fst (1, “one”) returns 1

– only usable on Tuples of Pairs!!!

fst (1,”one”,True) throws Exception!!!

● snd returns second element of a pair

snd (1, “one”) returns “one”

– only usable on Tuples of Pairs!!!– snd (1,”one”,True) throws Exception!!!

● zip creates a list of tuples from two lists

– zip [1,2,3] [“one”,“two”,”three”] returns [(1,“one”),(2,”two”),(3,”three”)]

Type Polymorphism (1)

● Statically typed, but Compiler can read type from context (type inference)

● → no need to set type explicitly

● → 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 of our previous implementations could befact :: Int -> Int

maxList :: [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 <function_name>

Typeclasses (1)

● define properties of the types

● like an interface

● Typeclasses:

– 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'])

Typeclasses (2)

● Typeclasses:

– Bounded upper/lower bound (minBound, maxBound)

– Num types behave like numbers (must already be Show, Eq)

– Integral contains only integrals (subclass of Num)

– Floating corresponding real numbers (subclass of Num)

● if all Types of tuple are in same Typeclass → Tuple also in Typeclass

Lazy Evaluation

● What happens, if I do this? (Yes it makes no sense, but just for demonstration)

max a b

| a > b = a

| otherwise = b

where temp = cycle “LOL ”

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)

top related