- 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
- 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
- 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
- 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
- Choosing between collection functions
- The "Object-oriented programming in F#" Series
- 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
- The "Porting from C#" Series
- The "Designing with types" Series
- Algebraic type sizes and domain modelling
- Thirteen ways of looking at a turtle
- How to design and code a complete program
- A functional approach to error handling (Railway oriented programming)
- The "Understanding monoids" Series
- The "Understanding Parser Combinators" Series
- The "Handling State" Series
- The "Map and Bind and Apply, Oh my!" Series
- The "Recursive types and folds" Series
- The "A functional approach to authorization" Series
- 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
- Enterprise Tic-Tac-Toe.
- Writing a JSON parser from scratch
- 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