1.
Why Haskell Matters
Roman Gonzalez
Vancouver Haskell Meetup
October 20, 2010
2.
So what is this language about?
Haskell is a pure, statically typed, lazy functional
programming language.
→ Name inspired by mathematician Haskell Brooks Curry
→ Based on a more primitive language called Lambda Calculus
→ There is no iteration or sequences of actions, everything is
recursive
3.
When learning Haskell is a good idea?
→ If you are a experienced developer that wants to grow
professionally by learning completely new and diﬀerent
approaches to solve problems
→ If you need to build systems where correctness is critical
(Banks, Safety-Critical Systems)
→ Is well suited to implement Domain Speciﬁc Languages, so it
could work very well in systems programming
→ as Erlang, it is easy to implement parallel and concurrent
programs safely due to the pureness of the language
4.
Beneﬁts of using Haskell
→ Algorithms are normally shorter and more concise than their
iterative versions
→ Due to the use of function composability, curryﬁcation and
high-order functions, code can be reused in really smart ways
→ The kick-ass type system with type inference makes you
develop code that would normally work at the ﬁrst compilation
5.
Properties of Haskell
→ Functions won’t perform sequentially, instead they will
evaluate expressions when needed (lazily)
→ There is a controlled environment for side eﬀect functions but
by default functions are pure (non-side eﬀect).
→ Management of resources is abstracted completely from the
developer (GC and automatic allocation of data included)
→ Strong typing makes correctness happen, and most of the the
issues regarding this type systems won’t get on the way due to
the compiler’s type inference system
6.
Quicksort in C
void qsort(int a[], int lo, int hi) {
int h, l, p, t;
if (lo < hi) {
l = lo;
h = hi;
p = a[hi];
do {
while ((l < h) && (a[l] <= p))
l = l+1;
while ((h > l) && (a[h] >= p))
h = h-1;
if (l < h) {
t = a[l];
a[l] = a[h];
a[h] = t;
}
} while (l < h);
a[hi] = a[l];
a[l] = p;
qsort( a, lo, l-1 );
qsort( a, l+1, hi );
}
}
8.
Simple Functions
One parameter functions
Haskell has only one parameter functions
inc :: Int -> Int
inc x = x + 1
isNotZero :: Int -> Bool
isNotZero x = x /= 0
9.
High Order Functions
Functions that returns functions
add :: Int -> (Int -> Int)
add x = y -> x + y
compare :: (Eq a) => a -> (a -> Bool)
compare a = b -> a == b
-- Syntactic Sugar complements of Haskell
add’ :: Int -> Int -> Int
add’ x y = x + y
compare’ :: (Eq a) => a -> a -> Bool
compare’ x y = x == y
10.
High Order Functions
Assign returned functions directly
If inc is a function of type:
Int -> Int
and (+1) is a function of type:
Int -> Int
Then why don’t assign it directly? This is called curryﬁcation
inc’ = (1 +)
isNotZero’ = (0 /=)
11.
High Order Functions
Functions that receive functions as parameters
Functions can also receive functions as parameters:
filter :: (a -> Bool) -> [a] -> [a]
filter fn (x:xs)
| fn x = x : filter fn xs
| otherwise = filter fn xs
-- filter isNotZero [1,0,2,0,3]
-- => [1,2,3]
They can also be curryﬁed:
removeZeros :: [Int] -> [Int]
removeZeros = filter isNotZero
12.
Lists
Deﬁnition of a list
→ An empty value: []
→ A cons value: Item on the left and list on the right, the whole
thing being a new list
[1,2,3] == (1:2:3:[]) == (1:(2:(3:[])))
So we have two basic functions to get the two components of a
cons:
head :: [a] -> a
head (x:_) = x
tail :: [a] -> [a]
tail (_:xs) = xs
13.
Let’s deﬁne some functions
Simple functions with a common interface
sum :: (Num a) => [a] -> a
sum [] = 0
sum (x:xs) = x + sum xs
prod :: (Num a) => [a] -> a
prod [] = 1
prod (x:xs) = x * prod xs
length :: [a] -> Int
length [] = 0
length (x:xs) = 1 + length xs
14.
Folding
Basics
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr fn zero [] = zero
foldr fn zero (x:xs) = fn x (foldr fn zero xs)
{-
foldr (+) 0 [3,2,5]
- [] is replaced by 0
- (:) function is replaced by the (+) function
-> 3 : (2 : (5 : []))
-> 3 + (2 + (5 + 0))
-}
15.
Folding
Using foldr and partially applied functions
-- foldr (+) 0 :: (Num a) => [a] -> a
sum’ = foldr (+) 0
-- foldr (*) 1 :: (Num a) => [a] -> a
prod’ = foldr (*) 1
-- foldr (+) 0 :: (Num a) => [a] -> a
length’ = foldr (_ accum -> 1 + accum) 0
16.
Folding
Insertion Sort
insertion :: (Ord a) => a -> [a] -> [a]
insertion a [] = [a]
insertion a (b:bs)
| a <= b = (a:b:bs)
| otherwise = (b : insertion a bs)
insertionSort :: (Ord a) => [a] -> [a]
insertionSort = foldr insertion []
{-
insertionSort [3,2,4]
-> insertion 3 (insertion 2 (insertion 4 ([])))
-}
17.
Function Composition
Basics
Let’s abstract the composition of functions
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(.) f g = x -> f (g x)
Using the (.) function, we can compose function together to
create new ones:
map :: (a -> b) -> [a] -> [b]
map fn = foldr ((:) . fn) []
-- (x:xs) == (:) x xs
-- (:) . fn = x -> (:) fn x
18.
Lazy Evaluation
Inﬁnite Lists
Haskell is a lazy language, meaning that the language will evaluate
expressions only one needed.
iterate :: (a -> a) -> a -> [a]
iterate fn a = (a : iterate fn (fn a))
-- [a, fn a, fn (fn a), fn (fn (fn a))), ...]
This will do an inﬁnite recursion, it will stop when algorithms do
not require more values from the inﬁnite lists
bitValues :: [Int]
bitValues = iterate (*2) 1
-- take 8 bitValues -> [1,2,4,8,16,32,64,128]
19.
Algebraic Data Types
Maybe Data Type
To handle nullable values we use an Algebraic Data Type called
Maybe
data Maybe a = Just a
| Nothing
deriving (Show)
Where the a in the Maybe could be any type (Int, String, Char)
Examples of values of type Maybe Int
→ Just 20
→ Nothing
20.
Unfolds
unfoldr :: (a -> Maybe (b, a)) -> a -> [b]
unfoldr fn x =
case fn x of
Just (a, b) -> a : (unfoldr fn b)
Nothing -> []
21.
From Int to [Bit]
type Bit = Int
nextBit :: Int -> Maybe (Bit, Int)
nextBit x
| x > 0 = Just (m, d)
| otherwise = Nothing
where
d = x ‘div‘ 2
m = x ‘mod‘ 2
toBinary :: Int -> [Bit]
toBinary = unfoldr nextBit
22.
Binary to Decimal
Example of high-order functions, composability and inﬁnite lists
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith _ _ [] = []
zipWith _ [] _ = []
zipWith fn (x:xs) (y:ys) = (fn x y) : zipWith fn xs ys
binaryToDecimal :: [Bit] -> Int
binaryToDecimal = sum . zipWith (*) bitValues
23.
Why Haskell is not being used as much?
→ It’s diﬀerent, people is always afraid of what is diﬀerent
→ It’s diﬃcult, mostly related to the ﬁrst point
→ It’s unpopular, mostly related to the ﬁrst and second point
→ It’s risky (for employers), there are not many Haskell
developers to count on, of course this is mostly related to the
ﬁrst, second and third point
→ Libraries are broad, but there is no depth (Many incompatible
experimental libraries that do the same thing)
24.
Thank You!
Get started at learnyouahaskell.com
Github: http://github.com/roman/haskell meetup
Twitter: @romanandreg
A particular slide catching your eye?
Clipping is a handy way to collect important slides you want to go back to later.
Be the first to comment