Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
1
Functional
programming f rom
its fundamentals
2
3
Beauvais Cathedral
Height of Ulm minister
161.5m
Height of Beauvais Cathedral
48m
4
Whoami I am
Software engineer at OpenValue
Co-organizer of FP Ams
Working at ING Bank
5
The goal of today
6
Content
Fundamentals of
functional
programming
LJ
Why do we need
functional
programming
Common constructs
from the
fundamentals
7
What is functional
programming
8
A function is a mapping between a domain
and a codomain. The only effect of a function
is computing the result
Programming
with
mathematical
functions
9
Properties of a
function
Totality
A function must yield a value
for every possible input
Purity
A function’s only effect must be
the computation of its return
value
Determinism
A function must yield the same
result for the same input
10
Expressions can be replaced with their values without changing the meaning of the program
Referential
transparency
Integer x = 1
new Pair<Integer, Integer>(x, x)
new Pair<Integer, Integer>(1, 1)
public Integer random() { … }
Integer x = random();
new Pair<Integer, Integer>(x, x)
public Integer random() { … }
new Pair<Integer, Integer>(random(), random())
13
Creates a new function from two other
functions where the second function will be
called with the result of evaluating the first
function
Function
composition
14
Function
composition
public static Integer length(String s) {
return s.length();
}
public static Integer plus2(Integer x) {
return x + 2;
}
public static Integer lengthPlus2(String s) {
return plus2(length(s));
}
15
Function
composition
public static <IN, MID, OUT> Function<IN, OUT> compose(Function<IN, MID> fst, Function<MID, OUT> snd) {
return (x -> snd.apply(fst.apply(x)));
}
16
Function
composition
Main.compose(Main::length, Main::plus2);
17
18
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(.) g f = a -> g (f a)
Function
composition
19
length :: String -> Int
plus2 :: Int -> Int
lengthPlus2 :: String -> Int -- lengthPlus2 "Hello Crowd!" -- 14
lengthPlus2 = plus2 . length
Function
composition
20
String -> Int
Int -> Int
Function
composition
21
Referential transparency
Function composition
Recap
ƽ
22
Why do we need
functional programming
23
Why do we need
functional
programming
Concurrency & Parallelism Easier to reason aboutReducing cognitive load
24
public class Class1 {
public String head(List<String> list) {
if (list.size() <= 0) {
return null;
}
return list.get(0);
}
}
Example 1
25
public class Class2 {
public Integer program(List<String> list) {
// can produce null pointer if list is empty
return head(list).length();
}
}
Example 1
26
public class Class1 {
public Optional<String> head(List<String> list) {
if (list.size() <= 0) {
return Optional.empty();
}
return Optional.of(list.get(0));
}
}
Example 2
27
public class Class2 {
public Optional<Integer> program(List<String> list) {
if (head(list).isPresent()) {
return Optional.of(head(list).get().length());
} else {
return Optional.empty();
}
}
}
Example 2
28
Common constructs f rom
the fundamentals
29
Translating a function that takes multiple
arguments into evaluating a sequence of
functions, each with a single argument.
Currying
30
(+) :: Int -> Int -> Int -- (+) 2 3 == 5
Currying
31
(+) :: Int -> (Int -> Int) -- (+) 2 3 == 5
Currying
32
doSomething :: String -> Int -> Double -> Int -> Int
-- doSomething “test” 1 1.0 5 == 9
Currying
33
doSomething :: String -> (Int -> (Double -> (Int -> Int)))
-- doSomething “test” 1 1.0 5 == 9
Currying
34
(+) :: Int -> (Int -> Int)
plus2 :: Int -> Int
plus2 = (+) 2 -- plus2 5 == 7
Currying
35
A tool to perform ad-hoc polymorphism in a
functional programming language
Type classes
36
public class Class1 {
public Optional<String> head(List<String> list) {
if (list.size() <= 0) {
return Optional.empty();
}
return Optional.of(list.get(0));
}
}
Polymorphism
in life
37
-- sortString [“ba”, “ab”, “cd”] == [“ab”, “ba”, “cd”]
sortString :: [String] -> [String]
sortString [] = []
sortString (p:xs) =
(sortString lesser) ++ [p] ++ (sortString greater)
where
lesser = filter (< p) xs
greater = filter (>= p) xs
Code
duplication
38
-- sortInteger [1, 3, 2] == [1, 2, 3]
sortInteger :: [Integer] -> [Integer]
sortInteger [] = []
sortInteger (p:xs) =
(sortInteger lesser) ++ [p] ++ (sortInteger greater)
where
lesser = filter (< p) xs
greater = filter (>= p) xs
Code
duplication
39
class Ord a where
(<) :: a -> a -> Bool
(<=) :: a -> a -> Bool
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
(>) :: a -> a -> Bool
(>=) :: a -> a -> Bool
Ord
typeclass
40
instance Ord Integer where
(<) a b = …
(<=) a b = …
(==) a b = …
(/=) a b = …
(>) a b = …
(>=) a b = …
Ord
instance for
Integer
41
Generalized
sort :: Ord a => [a] -> [a]
sort [] = []
sort (p:xs) = (sort lesser) ++ [p] ++ (sort greater)
where
lesser = filter (< p) xs
greater = filter (>= p) xs
42
Currying & Partial
application
Typeclasses
Recap
ƽ
43
Abstract over type constructors that can be
mapped over
Functor
44
repA :: Int -> List Char -- repA 3 == aaa
asciiNumber :: Char -> Int -- asciiNumber ‘a’ == 97
When
function
composition
doesn't f it
45
Int -> List Char
Char -> Int
When
function
composition
doesn't f it
46
Mapping
over the
value in a
context
fmap :: (a -> b) —> List a —> List b
47
Mapping
over the
value in a
context
repA :: Int -> List Char -- repA 3 == aaa
asciiNumber :: Char -> Int -- asciiNumber ‘a’ == 97
composed :: Int -> List Int -- composed 2 == [97, 97]
composed x = fmap asciiNumber (repA x)
fmap :: (a -> b)
—> List a —> List b
48
Lifting a
function in
a context
length :: String -> Int -- length “example” == 7
-- listLength [“example”, “test”] == [7, 4]
listLength :: List String -> List Int
listLength = fmap length
fmap :: (a -> b)
—> List a —> List b
49
Abstracting
over f map
-- fproduct [1, 2, 3] ((+) 1) == [(1,2), (2, 3), (3, 4)]
fproduct :: List a -> (a -> b) -> List (a, b)
fproduct list f = fmap (a -> (a, f a)) list
50
Abstracting
over f map
-- fproduct (Just 5) ((+) 1) == Just (5, 6)
fproduct :: Maybe a -> (a -> b) -> Maybe (a, b)
fproduct ma f = fmap (a -> (a, f a)) ma
51
Abstracting
over f map
fproduct :: IO a -> (a -> b) -> IO (a, b)
fproduct ma f = fmap (a -> (a, f a)) ma
52
Code
duplication
fproduct :: List a -> (a -> b) -> List (a, b)
fproduct ma f = fmap (a -> (a, f a)) ma
fproduct :: Maybe a -> (a -> b) -> Maybe (a, b)
fproduct ma f = fmap (a -> (a, f a)) ma
fproduct :: IO a -> (a -> b) -> IO (a, b)
fproduct ma f = fmap (a -> (a, f a)) ma
53
Functor
typeclass
class Functor f where
fmap :: (a -> b) -> f a -> f b
54
IO List Maybe
Functor
Hierarchy
55
Functor for
optionality
instance Functor Maybe where
fmap :: (a -> b) -> Maybe a -> Maybe b
fmap f (Just x) = Just $ f x
fmap f Nothing = Nothing
56
Functor for
List
instance Functor List where
fmap :: (a -> b) -> List a -> List b
fmap f [] = []
fmap f (x:xs) = f x : fmap f xs
57
Generalizing
f product
function
fproduct :: Functor f => f a -> (a -> b) -> f (a, b)
fproduct ma f = fmap (a -> (a, f a)) ma
58
Impossible
in Java
class Functor<F<>> {
}
59
Transforming values in
context
Functor typeclass allows
polymorphism
Recap
ƽ
60
Combine computations that depend on each
other
Monad
61
When
functor is
not enough
head :: List Int -> Maybe Int
head [] = Nothing
head (x:xs) = Just x
-- fiveDivBy 2 == Just 2.5
-- fiveDivBy 0 == Nothing
fiveDivBy :: Int -> Maybe Int
fiveDivBy 0 = Nothing
fiveDivBy x = Just (5 / x)
62
Map over f
with g
resulting in
context
List Int -> Maybe Int
Int -> Maybe Int
63
When
functor is
not enough
composed list = fmap fiveDivBy (head list)
64
When
functor is
not enough
composed :: List Int -> Maybe Maybe Int
composed list = fmap fiveDivBy (head list)
65
When
functor is
not enough
composed :: List Int -> Maybe Maybe Int
composed list = fmap fiveDivBy (head list)
-- composed [1, 2] == Just (Just 5)
-- composed [] == Nothing
-- composed [0, 3] == Just (Nothing)
66
When
functor is
not enough
composed :: List Int -> Maybe Int
composed list = flatten (fmap fiveDivBy (head list))
-- composed [1, 2] == Just 5
-- composed [] == Nothing
-- composed [0, 3] == Nothing
67
The Monad
typeclass
class Monad m where
return :: a -> m a
fmap :: (a -> b) -> m a -> m b
flatten :: m (m a) -> m a
68
The Monad
typeclass
class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
69
The Monad
typeclass
class Monad m where
return :: a -> m a
fmap :: (a -> b) -> m a -> m b
flatten :: m (m a) -> m a
(>>=) :: m a -> (a -> m b) -> m b
(>>=) ma f = flatten (fmap f ma)
70
The Monad
typeclass
instance Monad Maybe where
return :: a -> Maybe a
return x = Just x
fmap :: (a -> b) -> Maybe a -> Maybe b
fmap f (Just x) = Just (f x)
fmap f Nothing = Nothing
flatten :: Maybe (Maybe a) -> Maybe a
flatten (Just (Just x)) = Just x
flatten _ = Nothing
71
Composing
with Monads
head :: List Int -> Maybe Int
head [] = Nothing
head (x: xs) = Just x
fiveDivBy :: Int -> Maybe Int
fiveDivBy 0 = Nothing
fiveDivBy x = Just (5 / x)
72
Composing
with Monads
List Int -> Maybe Int
Int -> Maybe Int
Head
fiveDivBy
73
Composing
with Monads
composed :: List Int -> Maybe Int
composed list = flatten (fmap fiveDivBy (head list))
74
Composing
with Monads
composed :: List Int -> Maybe Int
composed list = (head list) >>= fiveDivBy
-- composed [1, 2] == Just 5
-- composed [] == Nothing
-- composed [0, 3] == Nothing
75
Abstracting
function
composition
with effects
List Int -> Maybe Int
Int -> Maybe Int
Head
fiveDivBy
76
Abstracting
function
composition
with effects
a -> Maybe b
b -> Maybe c
f
g
77
Abstracting
function
composition
with effects
a -> List b
b -> List c
f
g
78
Abstracting
function
composition
with effects
a -> IO b
b -> IO c
f
g
79
Abstracting
function
composition
with effects
listComposition :: (a -> List b) -> (b -> List c) -> (a -> List c)
listComposition f g = a -> (f a) >>= g
80
Abstracting
function
composition
with effects
maybeComposition :: (a -> Maybe b) -> (b -> Maybe c) -> (a -> Maybe c)
maybeComposition f g = a -> (f a) >>= g
81
Abstracting
function
composition
with effects
ioComposition :: (a -> IO b) -> (b -> IO c) -> (a -> IO c)
ioComposition f g = a -> (f a) >>= g
82
listComposition :: (a -> List b) -> (b -> List c) -> (a -> List c)
listComposition f g = a -> (f a) >>= g
maybeComposition :: (a -> Maybe b) -> (b -> Maybe c) -> (a -> Maybe c)
maybeComposition f g = a -> (f a) >>= g
ioComposition :: (a -> IO b) -> (b -> IO c) -> (a -> IO c)
ioComposition f g = a -> (f a) >>= g
83
listComposition :: (a -> List b) -> (b -> List c) -> (a -> List c)
listComposition f g = a -> (f a) >>= g
maybeComposition :: (a -> Maybe b) -> (b -> Maybe c) -> (a -> Maybe c)
maybeComposition f g = a -> (f a) >>= g
ioComposition :: (a -> IO b) -> (b -> IO c) -> (a -> IO c)
ioComposition f g = a -> (f a) >>= g
84
listComposition :: (a -> m b) -> (b -> m c) -> (a -> m c)
listComposition f g = a -> (f a) >>= g
maybeComposition :: (a -> m b) -> (b -> m c) -> (a -> m c)
maybeComposition f g = a -> (f a) >>= g
ioComposition :: (a -> m b) -> (b -> m c) -> (a -> m c)
ioComposition f g = a -> (f a) >>= g
85
Kleisli
composition
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
(>=>) f g = a -> (f a) >>= g
86
Kleisli
examples
head :: [a] -> Maybe a
head [] = Nothing
head (x:xs) = Just x
fiveDivBy :: Double -> Maybe Double
fiveDivBy 0 = Nothing
fiveDivBy x = Just (5 / x)
87
Kleisli
examples
composed :: [Double] -> Maybe Double
composed = head >=> fiveDivBy
88
Kleisli
examples
composed :: [Double] -> Maybe Double
composed = head >=> fiveDivBy
-- composed [1.0, 2.0, 3.0] == Just 5.0
-- composed [0.0, 1.0, 2.0] == Nothing
-- composed [] == Nothing
89
Kleisli
examples
composed :: [Double] -> Maybe Double
composed list = case head list of
Just x -> fiveDivBy x
Nothing -> Nothing
90
Kleisli
examples
another :: Double -> Maybe String
91
Kleisli
examples
composed :: [Double] -> Maybe String
composed = head >=> fiveDivBy >=> another
92
Kleisli
examples
composed :: [Double] -> Maybe String
composed list = case head list of
Just x -> case fiveDivBy x of
Just y -> another y
Nothing -> Nothing
Nothing -> Nothing
93
Monad allows sequencing
of computations
Monad typeclass for
abstracting over monads
Recap
ƽKleisli composition as
function composition
with embellished types
94
Beauty of
functional
programming
Function composition doesn’t fit all requirements anymore
We start with function composition
Beautiful abstractions to fit the new requirements
95
Let’s connect
Twitter
@MauroPalsgraaf
LinkedIn
mauropalsgraaf

More Related Content

Functional programming from its fundamentals