SlideShare a Scribd company logo
The
Functional Programming
Toolkit
(NDC Oslo 2019)
@ScottWlaschin
fsharpforfunandprofit.com
Why do functional programmers
use so many strange words?
Functional programming is scary
Functional programming is scary
Functional programming is scary
Object oriented programming is scary
These aren't just academic concepts.
They are actually useful tools!
Functional programmers have a
standard set of tools
map
traverse
bind
return
lift
The Functional Toolkit
• Composition
• Combination/Aggregation
• Iteration
• Working with effects
– Mixing effects and non-effects
– Chaining effects in series
– Working with effects in parallel
– Pulling effects out of a list
The Functional Toolkit
• Composition: compose
• Iteration: fold
• Combination/Aggregation: combine & reduce
• Working with effects
– Mixing effects and non-effects: map & return
– Chaining effects in series: bind/flatMap
– Working with effects in parallel: apply, lift, zip
– Pulling effects out of a list: sequence, traverse
FunctionalToolkit (FP jargon version)
• Combination/Aggregation: Monoid
• Working with effects
– Mixing effects and non-effects: Functor
– Chaining effects in series: Monad
– Working with effects in parallel: Applicative
FunctionalToolkit (FP jargon version)
• Combination/Aggregation: Monoid
• Working with effects
– Mixing effects and non-effects: Functor
– Chaining effects in series: Monad
– Working with effects in parallel: Applicative
This talk
This talk
A whirlwind tour of many sights
Don't worry if you don't understand everything
What I'll talk about
• The core principles of FP
• Function transformers
• Some tools in the functional toolkit
– map
– bind
– lift
• An example of using all the tools together
Core principles of
statically-typed FP
Part I
Core principles of (statically-typed) FP
Function
Functions are things
Composition everywhere
Core FP principle:
Functions are things
Function
The Tunnel of
Transformation
Function
apple -> banana
A function is a thing which
transforms inputs to outputs
A function is a standalone thing,
not attached to a class
It can be used for inputs and outputs
of other functions
input
A function can be an output
A function can be an output
output
A function can be an input
A function can be an input
input output
A function can be a parameter
A function can be a parameter
You can build very complex systems
from this simple foundation!
Most of the tools in the functional toolkit are "function
transformers" that convert functions to functions
Core FP principle:
Composition everywhere
Lego Philosophy
1. All pieces are designed to be connected
2. Connect two pieces together and get
another "piece" that can still be connected
3. The pieces are reusable in many contexts
All pieces are designed to be connected
Connect two pieces together and
get another "piece" that can still be connected
The pieces are reusable in different contexts
The Lego philosophy let's you make big things!
The Functional Programming Toolkit (NDC Oslo 2019)
Can we apply these ideas to
programming?
Functional Programming Philosophy
• Design functions that do one thing well
– Functions can be reused in different contexts
• Design functions to work together
– Expect the output of every function to become
the input to another, as yet unknown,function
• Use types to ensure that inputs match outputs
Function composition
Function 1
apple -> banana
Function 2
banana -> cherry
>>
Function 1
apple -> banana
Function 2
banana -> cherry
New Function
apple -> cherry
Can't tell it was built from
smaller functions!
Where did the banana go?
Building big things from functions
It's compositions all the way up
Low-level operation
ToUpper
stringstring
Low-level operation
Service
AddressValidator
A “Service” is just like a microservice
but without the "micro" in front
Validation
Result
Address
Low-level operation Low-level operation
Service
Use-case
UpdateProfileData
ChangeProfile
Result
ChangeProfile
Request
Service Service
Use-case
Web application
Http
Response
Http
Request
Use-case Use-case
Http
Response
Http
Request
A web application built from
functions only (no classes!)
Http
Response
Http
Request
I have a whole talk on "The Power of Composition" at
fsharpforfunandprofit.com/composition
A web application built from
functions only (no classes!)
Composition example in F#
let add1 x = x + 1
let double x = x + x
Introducing F#
let add1 x = x + 1
let double x = x + x
let square = fun x -> x * x
Introducing F#
add1 5 // = 6
double (add1 5) // = 12
square (double (add1 5)) // = 144
How to compose functions together
add1 double square5 6 12 144
5 |> add1 // = 6
5 |> add1 |> double // = 12
5 |> add1 |> double |> square // = 144
Piping in F#
Problems with composition
Composition works well when
the types match up


Composition doesn't work well
when the types don't match up
Fix: Insert a converter function
into the pipeline
Converter
function
5 |> add1 |> strLen
// ^ error: expecting an int
5 |> add1 |> intToStr |> strLen
// ^ fixed!
F# example

What if the types match up but
they're wrapped in something?
Option< >

What if the types match up but
they're wrapped in something?
List< >
FunctionTransformers
Part II
FunctionTransformers
Part II
What do railways
have to do with
programming?
Receive request
Validate request
Lowercase the email
Update user record in DB
Return result to user
type Request = {
name: string;
email: string }
"As a user I want to update my name and email address"
string UpdateCustomer()
{
var request = receiveRequest();
validateRequest(request);
lowercaseEmail(request);
db.updateDbFromRequest(request);
return "OK";
}
string UpdateCustomerWithErrorHandling()
{
var request = receiveRequest();
var isValidated = validateRequest(request);
if (!isValidated) {
return "Request is not valid"
}
lowercaseEmail(request);
db.updateDbFromRequest(request);
smtpServer.sendEmail(request.Email)
return "OK";
}
string UpdateCustomerWithErrorHandling()
{
var request = receiveRequest();
var isValidated = validateRequest(request);
if (!isValidated) {
return "Request is not valid"
}
lowercaseEmail(request);
var result = db.updateDbFromRequest(request);
if (!result) {
return "Customer record not found"
}
return "OK";
}
string UpdateCustomerWithErrorHandling()
{
var request = receiveRequest();
var isValidated = validateRequest(request);
if (!isValidated) {
return "Request is not valid"
}
lowercaseEmail(request);
try {
var result = db.updateDbFromRequest(request);
if (!result) {
return "Customer record not found"
}
} catch {
return "DB error: Customer record not updated"
}
return "OK";
}
string UpdateCustomerWithErrorHandling()
{
var request = receiveRequest();
var isValidated = validateRequest(request);
if (!isValidated) {
return "Request is not valid"
}
lowercaseEmail(request);
try {
var result = db.updateDbFromRequest(request);
if (!result) {
return "Customer record not found"
}
} catch {
return "DB error: Customer record not updated"
}
return "OK";
}
Use a Result type
for error handling
Request SuccessValidate
Failure
type Result =
| Ok of SuccessValue
| Error of ErrorValue
A choice type, aka sum type
Request SuccessValidate
Failure
let validateInput input =
if input.name = "" then
Error "Name must not be blank"
else if input.email = "" then
Error "Email must not be blank"
else
Ok input // happy path
validateInput
Step 1 Step 2 Step 3
Step 1 Step 2 Step 3
Functional flow without error handling
let updateCustomer =
receiveRequest()
|> validateRequest
|> lowercaseEmail
|> updateDbFromRequest
|> returnMessage
Before
One track
let updateCustomerWithErrorHandling =
receiveRequest()
|> validateRequest
|> lowercaseEmail
|> updateDbFromRequest
|> returnMessage
Functional flow with error handling
After
Two track
How to implement
Railway Oriented Programming
Success!
Failure
Input ->
Validate UpdateDbon success
bypass
Validate UpdateDb
How to compose
these functions?
Step 1 Step 2 Step 3
>> >>
Composing one-track functions is fine...
Step 1 Step 2 Step 3
>> >>
... and composing two-track functions is fine...
Step 1 Step 2 Step 3
 
... but composing switches is not allowed!
How to combine the
mismatched functions?
“Bind” is the answer!
Bind all the things!
Two-track input Two-track output
One-track input Two-track output


Two-track input
Slot for switch function
Two-track output
Two-track input Two-track output
let bind nextFunction twoTrackInput =
match twoTrackInput with
| Ok success -> nextFunction success
| Error err -> Error err
Two-track input Two-track output
let bind nextFunction twoTrackInput =
match twoTrackInput with
| Ok success -> nextFunction success
| Error err -> Error err
Two-track input Two-track output
let bind nextFunction twoTrackInput =
match twoTrackInput with
| Ok success -> nextFunction success
| Error err -> Error err
Two-track input Two-track output
©
let bind nextFunction twoTrackInput =
match twoTrackInput with
| Ok success -> nextFunction success
| Error err -> Error err
Two-track input Two-track output
Composing switches - review
Step 1 Step 2 Step 3
Step 1 Step 2 Step 3
Validation using Bind
Validating input
type Input = {
Name : string
Email : string
}
nameLessThan50
let nameNotBlank input =
if input.Name = "" then
Error "Name must not be blank"
else Ok input
Let nameLessThan50 input =
if input.Name.Length > 50 then
Error "Name must not be longer than 50 chars"
else Ok input
Let emailNotBlank input =
if input.Email = "" then
Error "Email must not be blank"
else Ok input
nameNotBlank
emailNotBlank
nameNotBlank (composed with)
nameLessThan50 (composed with)
emailNotBlank
nameNotBlank nameLessThan50 emailNotBlank
nameLessThan50 emailNotBlanknameNotBlank
nameNotBlank
bind nameLessThan50
bind emailNotBlank
request
|> nameNotBlank
|> Result.bind nameLessThan50
|> Result.bind emailNotBlank
name50 emailNotBlanknameNotBlank
validateInput
let validateInput input =
input
|> nameNotBlank
|> Result.bind nameLessThan50
|> Result.bind emailNotBlank
validateInput
Shapes vs.Types
FunctionB
Result<'TEntity,string>
FunctionA
Correct shape AND types match
Correct shape, but types don't match
How do single track functions
fit this model?
// trim spaces and lowercase
let lowercaseEmail input =
{input with
email = input.email.Trim().ToLower() }
lowercaseEmail
Won't compose!
UpdateDb EtcValidate
LowercaseEmail
Two-track input
Slot for one-track function
Two-track output
Two-track input Two-track output
lowercaseEmaillowercaseEmail
Two-track input Two-track output
let map singleTrackFunction twoTrackInput =
match twoTrackInput with
| Ok s -> Ok (singleTrackFunction s)
| Error e -> Error e
let map singleTrackFunction twoTrackInput =
match twoTrackInput with
| Ok s -> Ok (singleTrackFunction s)
| Error e -> Error e
Two-track input Two-track output
let map singleTrackFunction twoTrackInput =
match twoTrackInput with
| Ok s -> Ok (singleTrackFunction s)
| Error e -> Error e
Two-track input Two-track output
let map singleTrackFunction twoTrackInput =
match twoTrackInput with
| Ok s -> Ok (singleTrackFunction s)
| Error e -> Error e
Two-track input Two-track output
let map singleTrackFunction twoTrackInput =
match twoTrackInput with
| Ok s -> Ok (singleTrackFunction s)
| Error e -> Error e
Two-track input Two-track output
let map singleTrackFunction twoTrackInput =
match twoTrackInput with
| Ok s -> Ok (singleTrackFunction s)
| Error e -> Error e
Two-track input Two-track output
Converting one-track functions
UpdateDb EtcValidate
LowercaseEmail
Will compose
map
Converting everything to two-track
bind
map
Converting everything to two-track
These are "function
transformers"!
Validate LowercaseEmail DbUpdate
Using function transformers so that *can*
compose different shaped functions
map bind
Understanding "effects"
Part III
What is an effect?
• A collection type
List<_>
• A type enhanced with extra data
Option<_>, Result<_>
• A type that interacts with the outside world
Async<_>, Task<_>, Random<_>
• A type that carries state
State<_>, Parser<_>
What is an effect?
• A collection type
List<_>
• A type enhanced with extra data
Option<_>, Result<_>
• A type that interacts with the outside world
Async<_>, Task<_>, Random<_>
• A type that carries state
State<_>, Parser<_>
We'll focus on
three for this talk
"Normal" world vs.
"Effects" world
"Normal" world
int
string
bool
int -> string
int -> bool
"Option" world
Option<int>
Option<string>
Option<bool>
Option<int> -> Option<string>
Option<int> -> Option<bool>
"List" world
List<int>
List<string>
List<bool>
List<int> -> List<string>
List<int> -> List<bool>
"Async" world
Async<int>
Async<string>
Async<bool>
Async<int> -> Async<string>
Async<int> -> Async<bool>
Generic "Effects" world
E<int>
E<string>
E<bool>
E<int> -> E<string>
E<int> -> E<bool>
Different names, same concept
• "Effect" world
• "Enhanced" world
• "Elevated" world
– Because we use the word "lift" a lot!
How to work with effects?
Challenge:
Example scenario
• Download a URL into a JSON object
• Decode the JSON into a Customer DTO
• Convert the DTO into a valid Customer
• Store the Customer in a database
NormalWorld
Result World
AsyncWorld
Url
AsyncResult<Json,Err>
Download the json file
World of normal values
Result World
R<CustomerDto,Err>
Json
Decode the JSON into a DTO
World of normal values
Result World
R<name> R<email>
CustomerDto
Validate the fields of the customer
World of normal values
validName validEmail
validCustomer
Construct a customer from the fields
NormalWorld
Result World
AsyncWorld
Customer
AsyncResult<unit,Err>
Store the customer in the DB
How do we compose these
functions together?
None the worlds match up ...
... but we can use the functional toolkit!
Example:
Working with Options
World of normal values
int string bool
World of options
Option<int> Option<string> Option<bool>
World of options
World of normal values
int string bool
Option<int> Option<string> Option<bool>

World of options
World of normal values
Option<int> Option<string> Option<bool>

int string bool
add1 1 // 2
add1 (Some 1) // error
let add1ToOption opt =
if opt.IsSome then
let newVal = add1 opt.Value
Some newVal
else
None 
World of options
World of normal values
add1 
World of options
World of normal values
add1
Moving functions between
worlds with "map"
Tool #1
let add1ToOption opt =
if opt.IsSome then
Some (add1 opt.Value)
else
None
Let's take this code and turn it
into a generic, reusable tool
let optionMap f opt =
if opt.IsSome then
Some (f opt.Value)
else
None
let optionMap f =
fun opt ->
if opt.IsSome then
Some (f opt.Value)
else
None
let optionMap f
fun opt ->
if opt.IsSome then
Some (f opt.Value)
else
None
World of options
World of normal values
Option<T> -> -> Option<U>
optionMap
T -> -> U
let add1 x = ...
(optionMap add1) (Some 1)

Example:
Working with List world
let add1ToEach aList =
let newList = new List()
for item in aList do
let newItem = add1 item
newList.Add(newItem)
// return
newList

World of lists
World of normal values
add1 
let listMap f aList =
let newList = new List()
for item in aList do
let newItem = f item
newList.Add(newItem)
// return
newList
Let's make a generic, reusable
tool again
let listMap f aList =
let newList = new List()
for item in aList do
let newItem = f item
newList.Add(newItem)
// return
newList
let listMap f =
fun aList ->
let newList = new List()
for item in aList do
let newItem = f item
newList.Add(newItem)
// return
newList
World of lists
World of normal values
listMap
List<T> -> -> List<U>
T -> -> U
let add1 x = ...
(listMap add1) [1;2;3]
Q: Why is this any better than writing
your own loops every time?
A: Because it's a pattern you
can learn to recognize.
World of async
World of normal values
async<T> -> -> async<U>
asyncMap
T -> -> U
We do the same for other worlds too
Guideline:
Most wrapped generic types
have a “map”. Use it!
Guideline:
If you create your own generic type,
create a “map” for it.
FP terminology
A functor is
i. An effect type
– e.g. Option<>, List<>, Async<>
ii. Plus a "map" function that "lifts" a function to
the effects world
– a.k.a. select, lift
iii. And it must have a sensible implementation
– the Functor laws
Moving values between worlds
with "return"
Tool #2
World of options
World of normal values
Option<int>
Option.return
int
let x = 42
let intOption = Some x
World of lists
World of normal values
List<int>
List.return
int
let x = 42
let intList = [x]
Chaining world-crossing
functions with "bind"
Tool #3
What's a
world-crossing function?
let range max = [1..max]
// int -> List<int>
ListWorld
Normal world
A world crossing function
List<int>
int
range
let getCustomer id =
if customerFound then
Some customerData
else
None
// CustomerId -> Option<CustomerData>
OptionWorld
Normal world
A world crossing function
Option<CustomerData>
CustomerId
getCustomer
Problem:
How do you chain
world-crossing functions?
let optionExample input =
let x = doSomething input
if x.IsSome then
let y = doSomethingElse (x.Value)
if y.IsSome then
let z = doAThirdThing (y.Value)
if z.IsSome then
let result = z.Value
Some result
else
None
else
None
else
None
let taskExample input =
let taskX = startTask input
taskX.WhenFinished (fun x ->
let taskY = startAnotherTask x
taskY.WhenFinished (fun y ->
let taskZ = startThirdTask y
taskZ.WhenFinished (fun z ->
z // final result
)
)
)
How can we fix this?
let optionExample input =
let x = doSomething input
if x.IsSome then
let y = doSomethingElse (x.Value)
if y.IsSome then
let z = doAThirdThing (y.Value)
if z.IsSome then
// do something with z.Value
// in this block
else
None
else
None
else
None
Let's fix this!
There is a pattern we can exploit...
let optionExample input =
let x = doSomething input
if x.IsSome then
let y = doSomethingElse (x.Value)
if y.IsSome then
let z = doAThirdThing (y.Value)
if z.IsSome then
// do something with z.Value
// in this block
else
None
else
None
else
None
let optionExample input =
let x = doSomething input
if x.IsSome then
let y = doSomethingElse (x.Value)
if y.IsSome then
// do something with y.Value
// in this block
else
None
else
None
let optionExample input =
let x = doSomething input
if x.IsSome then
// do something with x.Value
// in this block
else
None
Can you see the pattern?
if opt.IsSome then
//do something with opt.Value
else
None
let ifSomeDo f opt =
if opt.IsSome then
f opt.Value
else
None
let example input =
doSomething input
|> ifSomeDo doSomethingElse
|> ifSomeDo doAThirdThing
|> ifSomeDo ...
let ifSomeDo f opt =
if opt.IsSome then
f opt.Value
else
None
Some
None
Input ->
Let's revisit the railway analogy
on Some
Bypass on None
The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 2019)
“Bind” is the answer (again!)
Option input Option output
One-track input Option output


Option input
Slot for switch function
Option output
Option input Option output
let bind nextFunction optionInput =
match optionInput with
| Some s -> nextFunction s
| None -> None
Option input Option output
let bind nextFunction optionInput =
match optionInput with
| Some s -> nextFunction s
| None -> None
Option input Option output
let bind nextFunction optionInput =
match optionInput with
| Some s -> nextFunction s
| None -> None
Option input Option output
let bind nextFunction optionInput =
match optionInput with
| Some s -> nextFunction s
| None -> None
Option input Option output
Pattern:
Use "bind" to chain options
let optionExample input =
let x = doSomething input
if x.IsSome then
let y = doSomethingElse (x.Value)
if y.IsSome then
let z = doAThirdThing (y.Value)
if z.IsSome then
let result = z.Value
Some result
else
None
else
None
else
None
Before
let optionBind f opt =
match opt with
| Some v -> f v
| None -> None
After
let optionExample input =
doSomething input
|> optionBind doSomethingElse
|> optionBind doAThirdThing
|> optionBind ...
let optionBind f opt =
match opt with
| Some v -> f v
| None -> None
No pyramids!
Code is linear and clear.
After
Pattern:
Use "bind" to chain tasks
a.k.a "promise" "future"
When task
completesWait Wait
let taskExample input =
let taskX = startTask input
taskX.WhenFinished (fun x ->
let taskY = startAnotherTask x
taskY.WhenFinished (fun y ->
let taskZ = startThirdTask y
taskZ.WhenFinished (fun z ->
z // final result
)
)
)
Before
let taskBind f task =
task.WhenFinished (fun taskResult ->
f taskResult)
let taskExample input =
startTask input
|> taskBind startAnotherTask
|> taskBind startThirdTask
|> taskBind ...
After
Why is bind so important?
It makes world-crossing functions
composable
EffectsWorld
Normal World
a
E<b>
Before bind:
A diagonal function
(world crossing)
bind
bind
EffectsWorld
Normal World
a
E<b>
EffectsWorld
Normal World
E<a> E<b>
After bind:
A horizontal function
(all in E-world)
bind
EffectsWorld
Normal World
a
E<b>
EffectsWorld
Normal World
E<a> E<b>
NormalWorld
Effects World
"Diagonal" functions can't be composed
NormalWorld
Effects World
Bind
NormalWorld
Effects World
Bind
NormalWorld
Effects World
Bind
NormalWorld
Effects World
"Horizontal" functions can be composed
FP terminology
A monad is
i. An effect type
– e.g. Option<>, List<>, Async<>
ii. Plus a return function
– a.k.a. pure unit
iii. Plus a bind function that converts a "diagonal"
(world-crossing) function into a "horizontal" (E-
world-only) function
– a.k.a. >>= flatMap SelectMany
iv. And bind/return must have sensible implementations
– the Monad laws
TLDR: If you want to chain effects-
generating functions in series,
use a Monad
Combining effects in parallel
with applicatives
Tool #4
How to combine effects?
Option<T> Option<U>+
Option<T,U>
Some 42 Some "hello"+
Some (42,"hello")
Combining options
This is what you expect!
Some 42 None+
None
Combining options
How to combine Lists?
List<T> List<U>+
List<T,U>
[1,2,3] ["a","b","c"]+
[ (1,"a"), (1,"b"), (1,"c")
(2,"a"), (2,"b"), (2,"c")
(3,"a"), (3,"b"), (3,"c") ]
Combining lists (cross product)
[1,2,3] ["a","b","c"]+
[ (1,"a")
(2,"b")
(3,"c") ]
Combining lists (zip)
The general term for this is
"applicative functor"
Option, List, Async are all applicatives
FP terminology
A applicative (functor) is
i. An effect type
– e.g. Option<>, List<>, Async<>
ii. Plus a return function
– a.k.a. pure unit
iii. Plus a function that combines two effects into one
– a.k.a. <*> apply pair liftA2
iv. And apply/return must have sensible implementations
– the Applicative Functor laws
So why is this useful?
Problem:
How to validate multiple fields
in parallel?
type Customer = {
Name : String50
Email : EmailAddress
Birthdate : Date
}
validateName validateEmail validateBirthdate
So we create some validation functions:
Each field must be validated
validateName validateEmail validateBirthdate
Problem: Validation done in series.
So only one error at a time is returned
type CustomerDto = {
name : string
email : string
birthdate : string
} validateName
validateEmail
validateBirthdate
Combine
output
Now we do get all
errors at once!
... But how to
combine them?
World of normal values
Result World
R<name> R<email> R<bdate>
validName validEmail validDate
World of normal values
validCustomer
We know how to combine the normal values
(use a constructor)
Result World
R<name> R<email> R<bdate>
R<Customer>
The output is also in
Result world
Use the magic
of Applicatives!
Introducing "liftA2", "liftA3", etc
ResultWorld
NormalWorld
Option<T>, Option<U> -> -> Option<V>
liftA2
T,U -> -> V
"liftA2" is just like map but works
on functions with two parameters
ResultWorld
NormalWorld
Opt<T>,Opt<U>,Opt<V> -> -> Option<W>
liftA3
T,U,V -> -> W
"liftA3" is just like map but works
on functions with three parameters
let dtoToCustomer (dto:CustomerDto) =
// get the validated values
let nameOrError = validateName dto.name
let emailOrError = validateEmail dto.email
let birthdateOrError =
validateBirthdate dto.birthdate
// call the constructor
(liftA3 makeCustomer)
nameOrError
emailOrError
birthdateOrError
// final output is Result<Customer,ErrMsg list>
Here's where the
magic happens!
What the code looks like
Let's review the tools
The FunctionalToolbox
• "map"
– Lifts functions into an effects world
• "return"
– Lifts values into an effects world
• "bind"
– Converts "diagonal" functions into "horizontal" ones so
they can be composed.
• "apply"
– Combines two effects in parallel
– "liftA2", "liftA3" for example
Using all the tools together
Part IV
Revisiting the example scenario
• Download a URL into a JSON object
• Decode the JSON into a Customer DTO
• Convert the DTO into a valid Customer
• Store the Customer in a database
NormalWorld
Result World
AsyncWorld
Download the json file
Url
AsyncResult<Json>
World of normal values
Result World
R<CustomerDto>
Json
Decode the json
World of normal values
Result World
R<name> R<email> R<bdate>
CustomerDto
Validate fields
World of normal values
Construct the customer
validName validEmail validDate
validCustomer
NormalWorld
Result World
AsyncWorld
Customer
Store the customer in the DB
AsyncResult<unit>
We now have the tools to compose
these functions together!
World of normal values
ResultWorld
R<name> R<email> R<bdate>
CustomerDto
Validate fields AND create a customer
Use Result type for validation
R<Customer>
Use "lift3"
World of normal values
Result World
CustomerDto
R<Customer>
Validate fields AND create a customer
We now have a world crossing function from
the DTO to the Customer
World of normal values
Result World
CustomerDto
R<Customer>
Parse json AND create a customer
R<CustomerDto>
Json
Use "bind" to turn the diagonal
functions into horizontal ones
Bind Bind
World of normal values
Result World
R<Customer>
Parse json AND create a customer
R<CustomerDto>R<Json>
Bind Bind
World of normal values
Result World
Parse json AND create a customer
R<Customer>R<Json>
Then compose them into one function
let jsonToCustomer jsonOrError =
jsonOrError
|> Result.bind jsonToCustomerDto
|> Result.bind dtoToCustomer
What the code looks like
It takes much more time to explain
than to write it!
NormalWorld
Result World
AsyncWorld
Parse json AND create a customer
R<Customer>R<Json>
Then lift it up to Async
world using map
Map
NormalWorld
Result World
AsyncWorld
Parse json AND create a customer
AsyncResult<Customer>AsyncResult<Json>
NormalWorld
AsyncWorld
Customer
Store the customer in the DB
Use "bind" to turn the
diagonal function horizontal
AsyncResult<unit>
Bind
NormalWorld
Result World
AsyncWorld
AsyncResult<Customer> AsyncResult<unit>
Store the customer in the DB
Bind
NormalWorld
AsyncWorld
All steps are now composable
Url
AsyncResult<Json>
AsyncResult<Customer>AsyncResult<Json>
AsyncResult<Customer> AsyncResult<unit>
Convert JSON to customer
Store customer in DB
NormalWorld
AsyncWorld
All steps are now composable
Url
AsyncResult<Json> AsyncResult<Customer> AsyncResult<unit>
NormalWorld
AsyncWorld
All steps are now composable into one single function
Url
AsyncResult<unit>
let jsonToCustomer jsonOrError =
jsonOrError
|> Result.bind jsonToCustomerDto
|> Result.bind dtoToCustomer
let downloadAndStoreCustomer url =
url
|> downloadFile
|> Async.map jsonToCustomer
|> AsyncResult.bind storeCustomerInDb
What the code looks like
The patterns might be unfamiliar but once you get
use to them, you can compose code quickly.
Again, it takes much more time to explain than to write it!
Language support for monads
• F# has computation expressions
• Haskell has "do" notation
• Scala has "for" comprehensions
• C# has "SelectMany" 
a.k.a. using "bind" everywhere gets ugly
In conclusion…
• FP jargon is not that scary
– Can you see why monads are useful?
• The FP toolkit is very generic
– FP's use these core functions constantly!
• You can now recognize "map", "lift" and "bind"
– Don’t expect to understand them all straight away.
"The Functional ProgrammingToolkit"
– Slides and video will be posted at
• fsharpforfunandprofit.com/fptoolkit
Related talks
– "Functional Design Patterns"
• fsharpforfunandprofit.com/fppatterns
– "The Power of Composition"
• fsharpforfunandprofit.com/composition
– "Domain Modeling Made Functional"
• fsharpforfunandprofit.com/ddd
Thanks!
Twitter:@ScottWlaschin

More Related Content

What's hot (20)

PDF
Railway Oriented Programming
Scott Wlaschin
 
PDF
Domain Modeling with FP (DDD Europe 2020)
Scott Wlaschin
 
PDF
Applicative Functor
Philip Schwarz
 
PPTX
Functional Programming in JavaScript by Luis Atencio
Luis Atencio
 
PPTX
Clean code
ifnu bima
 
PDF
Designing with Capabilities
Scott Wlaschin
 
PDF
The Power of Composition
Scott Wlaschin
 
PDF
Four Languages From Forty Years Ago
Scott Wlaschin
 
PDF
Monad as functor with pair of natural transformations
Philip Schwarz
 
PDF
Thirteen ways of looking at a turtle
Scott Wlaschin
 
PDF
Domain Driven Design with the F# type System -- NDC London 2013
Scott Wlaschin
 
PDF
The New JavaScript: ES6
Rob Eisenberg
 
PDF
Domain Modeling Made Functional (DevTernity 2022)
Scott Wlaschin
 
PDF
Dr Frankenfunctor and the Monadster
Scott Wlaschin
 
PPT
Oops concepts in php
CPD INDIA
 
PDF
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Philip Schwarz
 
PPT
Advanced Javascript
Adieu
 
PPT
Refactoring Tips by Martin Fowler
Igor Crvenov
 
PPTX
Refactoring and code smells
Paul Nguyen
 
PPTX
Avoiding callback hell in Node js using promises
Ankit Agarwal
 
Railway Oriented Programming
Scott Wlaschin
 
Domain Modeling with FP (DDD Europe 2020)
Scott Wlaschin
 
Applicative Functor
Philip Schwarz
 
Functional Programming in JavaScript by Luis Atencio
Luis Atencio
 
Clean code
ifnu bima
 
Designing with Capabilities
Scott Wlaschin
 
The Power of Composition
Scott Wlaschin
 
Four Languages From Forty Years Ago
Scott Wlaschin
 
Monad as functor with pair of natural transformations
Philip Schwarz
 
Thirteen ways of looking at a turtle
Scott Wlaschin
 
Domain Driven Design with the F# type System -- NDC London 2013
Scott Wlaschin
 
The New JavaScript: ES6
Rob Eisenberg
 
Domain Modeling Made Functional (DevTernity 2022)
Scott Wlaschin
 
Dr Frankenfunctor and the Monadster
Scott Wlaschin
 
Oops concepts in php
CPD INDIA
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Philip Schwarz
 
Advanced Javascript
Adieu
 
Refactoring Tips by Martin Fowler
Igor Crvenov
 
Refactoring and code smells
Paul Nguyen
 
Avoiding callback hell in Node js using promises
Ankit Agarwal
 

Similar to The Functional Programming Toolkit (NDC Oslo 2019) (20)

PDF
Reinventing the Transaction Script (NDC London 2020)
Scott Wlaschin
 
ODP
Functional programming
S M Asaduzzaman
 
PPTX
Functional programming for production quality code
Jack Fox
 
PDF
Fp for the oo programmer
Shawn Button
 
PDF
Functional programming is the most extreme programming
samthemonad
 
PDF
Functional Programming in C#: How to write better C# code 1st Edition Enrico ...
tomaimaschjt
 
PPTX
Thinking Functionally with JavaScript
Luis Atencio
 
PDF
The Power Of Composition (DotNext 2019)
Scott Wlaschin
 
PPSX
Functional patterns and techniques in C#
Péter Takács
 
PDF
Functional Programming for Busy Object Oriented Programmers
Diego Freniche Brito
 
PDF
Introduction to Functional Programming
Hoàng Lâm Huỳnh
 
PDF
Functional Programming with Javascript
Deepankar Chopra
 
PDF
379008-rc217-functionalprogramming
Luis Atencio
 
PDF
Introduction to Functional Programming (w/ JS)
Allan Marques Baptista
 
PDF
Christian Gill ''Functional programming for the people''
OdessaJS Conf
 
PDF
[4DEV] Bartosz Sokół - Functional developer in object oriented world - how F#...
PROIDEA
 
PPTX
Functional programming (Let's fall back in love with Programming)
Sudipta Mukherjee
 
PDF
JSDC 2014 - functional java script, why or why not
ChengHui Weng
 
PPTX
How Functional Programming Made Me A Better Developer
Cameron Presley
 
PPTX
Столпы функционального программирования для адептов ООП, Николай Мозговой
Sigma Software
 
Reinventing the Transaction Script (NDC London 2020)
Scott Wlaschin
 
Functional programming
S M Asaduzzaman
 
Functional programming for production quality code
Jack Fox
 
Fp for the oo programmer
Shawn Button
 
Functional programming is the most extreme programming
samthemonad
 
Functional Programming in C#: How to write better C# code 1st Edition Enrico ...
tomaimaschjt
 
Thinking Functionally with JavaScript
Luis Atencio
 
The Power Of Composition (DotNext 2019)
Scott Wlaschin
 
Functional patterns and techniques in C#
Péter Takács
 
Functional Programming for Busy Object Oriented Programmers
Diego Freniche Brito
 
Introduction to Functional Programming
Hoàng Lâm Huỳnh
 
Functional Programming with Javascript
Deepankar Chopra
 
379008-rc217-functionalprogramming
Luis Atencio
 
Introduction to Functional Programming (w/ JS)
Allan Marques Baptista
 
Christian Gill ''Functional programming for the people''
OdessaJS Conf
 
[4DEV] Bartosz Sokół - Functional developer in object oriented world - how F#...
PROIDEA
 
Functional programming (Let's fall back in love with Programming)
Sudipta Mukherjee
 
JSDC 2014 - functional java script, why or why not
ChengHui Weng
 
How Functional Programming Made Me A Better Developer
Cameron Presley
 
Столпы функционального программирования для адептов ООП, Николай Мозговой
Sigma Software
 
Ad

More from Scott Wlaschin (11)

PDF
Building confidence in concurrent code with a model checker: TLA+ for program...
Scott Wlaschin
 
PDF
The Functional Programmer's Toolkit (NDC London 2019)
Scott Wlaschin
 
PDF
Domain Modeling Made Functional (KanDDDinsky 2019)
Scott Wlaschin
 
PDF
F# for C# Programmers
Scott Wlaschin
 
PDF
Designing with capabilities (DDD-EU 2017)
Scott Wlaschin
 
PDF
Enterprise Tic-Tac-Toe
Scott Wlaschin
 
PDF
An introduction to property based testing
Scott Wlaschin
 
PDF
Swift vs. Language X
Scott Wlaschin
 
PDF
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Scott Wlaschin
 
PDF
Doge-driven design
Scott Wlaschin
 
PDF
The Theory of Chains
Scott Wlaschin
 
Building confidence in concurrent code with a model checker: TLA+ for program...
Scott Wlaschin
 
The Functional Programmer's Toolkit (NDC London 2019)
Scott Wlaschin
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Scott Wlaschin
 
F# for C# Programmers
Scott Wlaschin
 
Designing with capabilities (DDD-EU 2017)
Scott Wlaschin
 
Enterprise Tic-Tac-Toe
Scott Wlaschin
 
An introduction to property based testing
Scott Wlaschin
 
Swift vs. Language X
Scott Wlaschin
 
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Scott Wlaschin
 
Doge-driven design
Scott Wlaschin
 
The Theory of Chains
Scott Wlaschin
 
Ad

Recently uploaded (20)

PDF
AOMEI Partition Assistant Crack 10.8.2 + WinPE Free Downlaod New Version 2025
bashirkhan333g
 
PDF
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
PDF
Technical-Careers-Roadmap-in-Software-Market.pdf
Hussein Ali
 
PDF
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
PDF
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
PPTX
Customise Your Correlation Table in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PPTX
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
PPTX
Help for Correlations in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PPTX
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
PDF
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
PDF
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
PDF
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
PPTX
Tally software_Introduction_Presentation
AditiBansal54083
 
PDF
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
PDF
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
PDF
Generic or Specific? Making sensible software design decisions
Bert Jan Schrijver
 
PDF
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
PDF
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
PPTX
Empowering Asian Contributions: The Rise of Regional User Groups in Open Sour...
Shane Coughlan
 
AOMEI Partition Assistant Crack 10.8.2 + WinPE Free Downlaod New Version 2025
bashirkhan333g
 
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
Technical-Careers-Roadmap-in-Software-Market.pdf
Hussein Ali
 
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
Customise Your Correlation Table in IBM SPSS Statistics.pptx
Version 1 Analytics
 
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
Help for Correlations in IBM SPSS Statistics.pptx
Version 1 Analytics
 
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
Tally software_Introduction_Presentation
AditiBansal54083
 
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
Generic or Specific? Making sensible software design decisions
Bert Jan Schrijver
 
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
Empowering Asian Contributions: The Rise of Regional User Groups in Open Sour...
Shane Coughlan
 

The Functional Programming Toolkit (NDC Oslo 2019)