F# for Fun and Profit
  • Introduction
  • Getting started
    • Contents of the book
    • "Why use F#?" in one page
    • Installing and using F#
    • F# syntax in 60 seconds
    • Learning F#
    • Troubleshooting F#
    • Low-risk ways to use F# at work
      • Twenty six low-risk ways to use F# at work
      • Using F# for development and devops scripts
      • Using F# for testing
      • Using F# for database related tasks
      • Other interesting ways of using F# at work
  • Why use F#?
    • The "Why use F#?" Series
      • Introduction to the 'Why use F#' series
      • F# syntax in 60 seconds
      • Comparing F# with C#: A simple sum
      • Comparing F# with C#: Sorting
      • Comparing F# with C#: Downloading a web page
      • Four Key Concepts
      • Conciseness
      • Type inference
      • Low overhead type definitions
      • Using functions to extract boilerplate code
      • Using functions as building blocks
      • Pattern matching for conciseness
      • Convenience
      • Out-of-the-box behavior for types
      • Functions as interfaces
      • Partial Application
      • Active patterns
      • Correctness
      • Immutability
      • Exhaustive pattern matching
      • Using the type system to ensure correct code
      • Worked example: Designing for correctness
      • Concurrency
      • Asynchronous programming
      • Messages and Agents
      • Functional Reactive Programming
      • Completeness
      • Seamless interoperation with .NET libraries
      • Anything C# can do...
      • Why use F#: Conclusion
  • Thinking Functionally
    • The "Thinking Functionally" Series
      • Thinking Functionally: Introduction
      • Mathematical functions
      • Function Values and Simple Values
      • How types work with functions
      • Currying
      • Partial application
      • Function associativity and composition
      • Defining functions
      • Function signatures
      • Organizing functions
      • Attaching functions to types
      • Worked example: A stack based calculator
  • Understanding F# ###
    • The "Expressions and syntax" Series
      • Expressions and syntax: Introduction
      • Expressions vs. statements
      • Overview of F# expressions
      • Binding with let, use, and do
      • F# syntax: indentation and verbosity
      • Parameter and value naming conventions
      • Control flow expressions
      • Exceptions
      • Match expressions
      • Formatted text using printf
      • Worked example: Parsing command line arguments
      • Worked example: Roman numerals
    • The "Understanding F# types" Series
      • Understanding F# types: Introduction
      • Overview of types in F#
      • Type abbreviations
      • Tuples
      • Records
      • Discriminated Unions
      • The Option type
      • Enum types
      • Built-in .NET types
      • Units of measure
      • Understanding type inference
    • Choosing between collection functions
    • The "Object-oriented programming in F#" Series
      • Object-oriented programming in F#: Introduction
      • Classes
      • Inheritance and abstract classes
      • Interfaces
      • Object expressions
    • The "Computation Expressions" Series
      • Computation expressions: Introduction
      • Understanding continuations
      • Introducing 'bind'
      • Computation expressions and wrapper types
      • More on wrapper types
      • Implementing a builder: Zero and Yield
      • Implementing a builder: Combine
      • Implementing a builder: Delay and Run
      • Implementing a builder: Overloading
      • Implementing a builder: Adding laziness
      • Implementing a builder: The rest of the standard methods
    • Organizing modules in a project
    • The "Dependency cycles" Series
      • Cyclic dependencies are evil
      • Refactoring to remove cyclic dependencies
      • Cycles and modularity in the wild
    • The "Porting from C#" Series
      • Porting from C# to F#: Introduction
      • Getting started with direct porting
  • Functional Design ###
    • The "Designing with types" Series
      • Designing with types: Introduction
      • Single case union types
      • Making illegal states unrepresentable
      • Discovering new concepts
      • Making state explicit
      • Constrained strings
      • Non-string types
      • Designing with types: Conclusion
    • Algebraic type sizes and domain modelling
    • Thirteen ways of looking at a turtle
      • Thirteen ways of looking at a turtle (part 2)
      • Thirteen ways of looking at a turtle - addendum
  • Functional Patterns ###
    • How to design and code a complete program
    • A functional approach to error handling (Railway oriented programming)
      • Railway oriented programming: Carbonated edition
    • The "Understanding monoids" Series
      • Monoids without tears
      • Monoids in practice
      • Working with non-monoids
    • The "Understanding Parser Combinators" Series
      • Understanding Parser Combinators
      • Building a useful set of parser combinators
      • Improving the parser library
      • Writing a JSON parser from scratch
    • The "Handling State" Series
      • Dr Frankenfunctor and the Monadster
      • Completing the body of the Monadster
      • Refactoring the Monadster
    • The "Map and Bind and Apply, Oh my!" Series
      • Understanding map and apply
      • Understanding bind
      • Using the core functions in practice
      • Understanding traverse and sequence
      • Using map, apply, bind and sequence in practice
      • Reinventing the Reader monad
      • Map and Bind and Apply, a summary
    • The "Recursive types and folds" Series
      • Introduction to recursive types
      • Catamorphism examples
      • Introducing Folds
      • Understanding Folds
      • Generic recursive types
      • Trees in the real world
    • The "A functional approach to authorization" Series
      • A functional approach to authorization
      • Constraining capabilities based on identity and role
      • Using types as access tokens
  • Testing
    • An introduction to property-based testing
    • Choosing properties for property-based testing
  • Examples and Walkthroughs
    • Worked example: Designing for correctness
    • Worked example: A stack based calculator
    • Worked example: Parsing command line arguments
    • Worked example: Roman numerals
    • Commentary on 'Roman Numerals Kata with Commentary'
    • Calculator Walkthrough: Part 1
      • Calculator Walkthrough: Part 2
      • Calculator Walkthrough: Part 3
      • Calculator Walkthrough: Part 4
    • Enterprise Tic-Tac-Toe
      • Enterprise Tic-Tac-Toe, part 2
    • Writing a JSON parser from scratch
  • Other
    • Ten reasons not to use a statically typed functional programming language
    • Why I won't be writing a monad tutorial
    • Is your programming language unreasonable?
    • We don't need no stinking UML diagrams
    • Introvert and extrovert programming languages
    • Swapping type-safety for high performance using compiler directives
Powered by GitBook
On this page
  • Series summary
  • Series contents
  • Appendix: List of operators mentioned
  • Appendix: Further reading

Was this helpful?

  1. Functional Patterns ###
  2. The "Map and Bind and Apply, Oh my!" Series

Map and Bind and Apply, a summary

PreviousReinventing the Reader monadNextThe "Recursive types and folds" Series

Last updated 5 years ago

Was this helpful?

Series summary

Well, turned out to be longer than I originally planned. Thanks for making it to the end!

I hope that this discussion has been helpful in understanding the various function transformations like map and bind, and given you some useful techniques for dealing with world-crossing functions -- maybe even demystified the m-word a bit!

If you want to start using these kinds of functions in your own code, I hope that you can see how easy they are to write, but you should also consider using one of the excellent F# utility libraries that contain these and much more:

  • ExtCore (, ). ExtCore provides extensions to the F# core library (FSharp.Core) and aims to help you build industrial-strength F# applications. These extensions include additional functions for modules such as Array, List, Set, and Map; immutable IntSet, IntMap, LazyList, and Queue collections; a variety of computation expressions (workflows); and "workflow collections" -- collections modules which have been adapted to work seamlessly from within workflows.

  • FSharpx.Extras (). FSharpx.Extras is part of the FSharpx series of libraries. It implements several standard monads (State, Reader, Writer, Either, Continuation, Distribution), validation with applicative functors, general functions like flip, and some asynchronous programming utilities, and functions to make C# - F# interop easier.

For example, the monadic traverse List.traverseResultM that I implemented is already available in ExtCore .

And if you liked this series, I have posts explaining the State monad in my series on and the Either monad in my talk .

As I said at the very beginning, writing this up has been a learning process for me too. I am not an expert, so if I have made any errors please do let me know.

Thanks!

Series contents

Here's a list of shortcuts to the various functions mentioned in this series:

  • Part 1: Lifting to the elevated world

  • Part 2: How to compose world-crossing functions

  • Part 3: Using the core functions in practice

  • Part 4: Mixing lists and elevated values

  • Part 5: A real-world example that uses all the techniques

  • Part 6: Designing your own elevated world

  • Part 7: Summary

Appendix: List of operators mentioned

Operator

Equivalent function

Discussion

>>

Left-to-right composition

<<

Right-to-left composition

As above

|>

Left-to-right piping

As above

<|

Right-to-left piping

As above

<!>

map

<$>

map

Haskell operator for map, but not a valid operator in F#, so I'm using <!> in this series.

<*>

apply

<*

-

*>

-

>>=

Left-to-right bind

=<<

Right-to-left bind

As above

>=>

Left-to-right Kleisli composition

<=<

Right-to-left Kleisli composition

As above

Appendix: Further reading

Alternative tutorials:

For the academically minded:

F# examples:

  • Applicatives are very well suited for parsing, as explained in these posts:

Unlike OO languages, functional programming languages are known for their , so I thought it would be helpful to document the ones that have been used in this series, with links back to the relevant discussion.

Not part of this series, but

One sided combiner.

One sided combiner.

.

.

. I think this one is funny.

.

(PDF), by Philip Wadler. One of the first monad papers.

(PDF), by Conor McBride and Ross Paterson.

(PDF), by Jeremy Gibbons and Bruno Oliveira.

and

have lots of useful code.

has map, apply, liftN (called "Parallel"), bind, and other useful extensions for Async.

.

.

strange operators
You Could Have Invented Monads! (And Maybe You Already Have)
Functors, Applicatives and Monads in pictures
Kleisli composition ? la Up-Goer Five
Eric Lippert's series on monads in C#
Monads for Functional Programming
Applicative Programming with Effects
The Essence of the Iterator Pattern
F# ExtCore
FSharpx.Extras
FSharpx.Async
Parsing with applicative functors in F#
Dive into parser combinators: parsing search queries with F# and FParsec in Kiln
discussed here
this series
source
NuGet
home page
here
"Dr Frankenfunctor and the Monadster"
"Railway Oriented Programming"
List of operators mentioned
Further reading
Discussed here
Discussed here
Discussed here
Discussed here
Discussed here
Discussed here
The bind function
List is not a monad. Option is not a monad.
Independent and dependent data
Example: Validation using applicative style and monadic style
Lifting to a consistent world
Kleisli world
The map function
The return function
The apply function
The liftN family of functions
The zip function and ZipList world
in this post
Mixing lists and elevated values
The traverse/MapM function
The sequence function
"Sequence" as a recipe for ad-hoc implementations
Readability vs. performance
Dude, where's my filter?
Example: Downloading and processing a list of websites
Treating two worlds as one
Designing your own elevated world
Filtering out failures
The Reader monad