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
  • Alice learns to count
  • How not to win friends and influence people
  • Why I won't be writing a monad tutorial
  • Why you should write a monad tutorial

Was this helpful?

  1. Other

Why I won't be writing a monad tutorial

PreviousTen reasons not to use a statically typed functional programming languageNextIs your programming language unreasonable?

Last updated 5 years ago

Was this helpful?

"A ?newbie', in Haskell, is someone who hasn't yet implemented a compiler. They've only written a monad tutorial" -

Let's start with a story...

Alice learns to count

Young Alice and her father (who happens to be a mathematician) are visiting a petting zoo...

Alice: Look at those kitties.

Daddy: Aren't they cute. There are two of them.

Alice: Look at those doggies.

Daddy: That's right. Can you count? There are two doggies.

Alice: Look at those horsies.

Daddy: Yes darling. Do you know what the kitties and doggies and horsies all have in common?

Alice: No. Nothing in common!

Daddy: Well, actually they do have something in common. Can you see what it is?

Alice: No! A doggy is not a kitty. A horsie is not a kitty.

Alice: [Bursts into tears]

How not to win friends and influence people

No (sensible) parent would ever try to explain how to count by starting with a formal definition of ordinal numbers.

So why is it that many people feel compelled to explain a concept like monads by emphasizing their formal definition?

That might be fine for a college-level math class, but it plainly does not work for regular programmers, who just want to create something useful.

Here's the truth: You don't need to understand monads to write useful functional code. This is especially true for F# compared to say, Haskell.

So really, don't worry about them.

Why I won't be writing a monad tutorial

So this is why I won't be writing a monad tutorial. I don't think it will help people learn about functional programming. If anything, it just creates confusion and anxiety.

Why you should write a monad tutorial

On the other hand, I do think that you should write a monad tutorial. When you try to explain something to somebody else, you end up understanding it better yourself.

Here's the process I think you should follow:

  1. First, write lots of practical code involving lists, sequences, options, async workflows, computation expressions, etc.

  2. As you become more experienced, you will start to use more abstractions, focusing on the shapes of things rather than the details.

  3. At some point, you will have an aha! moment -- a sudden insight that all the abstractions have something in common.

  4. Bingo! Time to write your monad tutorial!

Good luck with your tutorial -- I'm off to eat a burrito.

Daddy: How about I explain for you? First, let us consider . Does that give you a clue?

As an unfortunate result of this approach, though, there is now a whole mystique around the concept of monads. It has become on the way to true enlightenment. And there are, of course, a to help you cross it.

Monads are not a . They won't make you any more productive. They won't make your code less buggy.

Yes, I will use examples of monads in different , but, other than right here, I will try to avoid using the word "monad" anywhere on this site. In fact, it has pride of place on my !

The key point is that -- you cannot jump straight to the last step and then work backwards. It is the very act of working your way through the details that enables you to understand the abstraction when you see it.

a set S which is strictly well-ordered with respect to set membership and where every element of S is also a subset of S
a bridge you must cross
plethora of monad tutorials
golden hammer
many
posts
list of banned words
you have to do it in this order
Pseudonymn
two kitties
two kitties
two kitties