Learn F#
Isaac Abraham
  • MEAP began September 2016
  • Publication in Summer 2017 (estimated)
  • ISBN 9781617293993
  • 400 pages (estimated)
  • printed in black & white

F# is a mature, open-source functional-first language that's rapidly growing in popularity both inside and outside the .NET ecosystem. And while F# runs on the .NET framework and supports OO features, its functional nature is what's driving interest. F# leads to quicker development time and a lower total cost of ownership. Its powerful feature set allows developers to more succinctly express their intent, and encourages best practices - leading to higher quality deliverables in less time. Developers find working in F# more enjoyable and rewarding; their managers appreciate the improved quality and speed of deliverables!

Learn F# is a practical guide for experienced C# and .NET developers that teaches the F# language, tools, techniques, and practices that can be applied in common scenarios. You'll start with F# language basics and best development practices. You'll also learn the core set of FP techniques in F#, and why to use them. Then you'll discover how to write idiomatic F# code on the .NET framework in Visual Studio, and what tools to use to give you the best experience within VS. The second part of the book shows you how to apply F# in larger, real world scenarios, things like interop to C# /VB projects, SQL database access, web programming, and unit testing. By the end of the book, you'll be able to use F# in your day-to-day development, and know how and where to deepen your knowledge.

Table of Contents detailed table of contents

Welcome to Learn F#!

0.1 What is F# - and why does it matter?

0.1.1 What is F#?

0.1.2 F# alongside other programming languages

0.1.3 Why F#?

0.1.4 Working with a smarter compiler

0.1.5 What#s the catch?

0.2 What this book covers

0.2.1 Focusing on F# fundamentals

0.2.2 Real world libraries

0.2.3 Book structure

0.3 F# and .NET

0.3.1 F#s place within .NET

0.4 F# and Open Source

0.4.1 The F# community

0.4.2 Coding in the open source world

0.4.3 A real-world example of open source contributions

0.5 Summary

Unit 1: F# and Visual Studio

Lesson 1 The Visual Studio Experience

1.1.1 Installing VS2015 with F#

1.2 Configuring Visual Studio for F#

1.2.1 Visual F# Tools configuration

1.2.2 Configuring the F# Editor

1.3 Getting the best out of VS 2015 and F#

1.3.1 Installing Visual F# Power Tools

1.3.2 Configuring F# Syntax Highlighting

1.4 Summary

Lesson 2 Creating your first F# program

2.1 F# Project Types

2.2 Debugging applications in F#

2.3 Writing your first F# snippet

2.4 Summary

Lesson 3 The REPL - Changing how we develop

3.1 Priming exercise: Thinking about your development process

3.1.1 Application-based Development

3.1.2 Console Test Rigs

3.1.3 Automated unit tests

3.2 Enter the REPL

3.3 The F# REPL

3.3.1 State in FSI

3.4 F# Scripts in Visual Studio

3.5 Working with Scripts and FSI

3.5.1 Working with functions in scripts

3.6 Summary

Unit 2: Hello F#

Lesson 4 Saying a little, doing a lot

4.1 Priming Exercise: Thinking about syntax as the "character" of a language

4.2 Binding values in F#

4.2.1 Let isn't var!

4.3 Scoping values

4.3.1 Nested scopes

4.3.2 Nested functions

4.4 Summary

Lesson 5 Trusting the Compiler

5.1 A refresher on type inference today in C# and VB

5.2 Imagining a more powerful Type Inference system

5.3 Type Inference with F#

5.4 Limitations of type inference

5.4.1 Working with the BCL

5.4.2 Classes and Overloaded methods

5.5 Type Inferred Generics

5.6 Following the breadcrumbs

5.7 Summary

Lesson 6 Working with immutable data

6.1 Thinking about the mutable world in software development

6.1.1 The unrepeatable bug

6.1.2 Multithreading pitfalls

6.1.3 Accidentally sharing state

6.1.4 Testing hidden state

6.2 Being explicit about mutation

6.3 Working with mutable objects

6.4 Modelling state

6.4.1 Working with mutable data

6.4.2 Working with immutable data

6.4.3 Other benefits of immutable data

6.5 Summary

Lesson 7 Expressions and Statements

7.1 What are expressions and statements?

7.2 Priming exercise: How statements can make life difficult

7.3 Making life better through Expressions

7.4 Expressions in F#

7.5 Composability

7.6 Introducing Unit

7.7 Trusting the compiler again

7.8 Escape hatches

7.9 Forcing statement-based evaluation

7.10 Summary

Lesson 8 Capstone 1

8.1 Defining the problem

8.2 Some advice before you start..

8.3 Starting small

8.3.1 Solution overview

8.4 Implementing core logic

8.4.1 Our first function - calculating distances

8.4.2 Calculating petrol consumption

8.4.3 Composing functions together

8.4.4 Stopping at the Gas station

8.5 Testing in scripts

8.6 Moving to a full application

8.7 Summary

Unit 3 : Types and Functions

Lesson 9 Shaping data with Tuples

9.1 Priming exercise - returning data from a method

9.2 Tuples in F#

9.2.1 When should I use tuples?

9.3 More complex tuples

9.3.1 Tuple Type Signatures

9.3.2 Nested Tuples

9.3.3 Wildcards

9.4 Type Inference with Tuples

9.5 Tuple best practices

9.5.1 Tuples and the BCL

9.5.2 When not to use Tuples

9.6 Summary

Lesson 10 Shaping data with Records

10.1 Priming exercise - creating an immutable type in C#

10.2 POCOs done right - Records in F#

10.3 Creating Records

10.4 Type Inference with Records

10.5 Working with immutable Records

10.6 Equality Checking

10.7 Tips and tricks with Records

10.7.1 Refactorings

10.7.2 Shadowing

10.8 When to use records

10.9 Summary

Lesson 11 Building composable functions

11.1 Comparing methods and functions

11.2 Partial function application

11.3 Using Curried Functions

11.3.1 Constraining functions

11.3.2 Pipelines

11.3.3 Custom Fonts

11.3.4 Composing functions together

11.4 Summary

Lesson 12 Organising code without classes

12.1 Organising code elements in F#

12.2 Namespaces in F#

12.3 Modules in F#

12.3.1 Visualising namespaces and modules

12.3.2 Opening modules

12.4 Namespaces vs Modules

12.5 Moving from scripts to applications

12.6 Tips for working with Modules and Namespaces

12.6.1 Access Modifiers

12.6.2 The global namespace

12.6.3 Automatic namespacing

12.6.4 Automatic opening of modules

12.6.5 Scripts

12.7 Summary

Lesson 13 Achieving code reuse in F#

13.1 Priming Exercise: How do you reuse code today?

13.2 Reuse in the world of LINQ

13.3 Implementing higher order functions in F#

13.4 When to pass functions as arguments

13.5 Dependencies as functions

13.6 Summary

Lesson 14 Capstone 2

14.1 Defining the problem

14.2 Some advice before you start…​

14.3 Getting started

14.4 Creating a domain

14.5 Creating behaviours

14.6 Abstraction and reuse through higher order functions

14.6.1 Adapting code with higher order functions

14.7 Writing a console application

14.7.1 Writing the Program

14.7.2 Managing the account state

14.8 Referencing files from scripts

14.9 Summary

Unit 4: Collections in F#

Lesson 15 Working with collections in F#

15.1 Priming Exercise: Working with collections today

15.1.1 In place collection modifications

15.1.2 The collection modules

15.1.3 Transformation pipelines

15.1.4 Debugging pipelines

15.1.5 Compose, compose, compose

15.2 Collection Types in F#

15.2.1 Working with sequences

15.2.2 Using .NET arrays

15.2.3 Immutable Lists

15.2.4 Comparing and Contrasting Collections

15.3 Summary

Lesson 16 Useful collection functions

16.1 Mapping Functions

16.1.1 Map

16.1.2 Iter

16.1.3 Collect

16.1.4 Pairwise

16.2 Grouping functions

16.2.1 GroupBy

16.2.2 CountBy

16.2.3 Partition

16.3 Aggregate functions

16.4 Miscellaneous functions

16.5 Converting between collections

16.6 Summary

Lesson 17 Maps, Dictionaries and Sets

17.1 Dictionaries

17.1.1 Mutable dictionaries in F#

17.1.2 Immutable Dictionaries

17.2 The F# Map

17.2.1 Useful Map functions

17.3 Sets

17.4 Summary

Lesson 18 Folding our way to success

18.1 Understanding aggregations and accumulators

18.1.1 Creating our first Aggregation function

18.2 Saying hello to fold

18.2.1 Making fold more readable

18.3 Folding instead of while loops

18.4 Composing functions with fold

18.4.1 Composing rules manually

18.4.2 Folding functions together

18.5 Summary

Lesson 19 Capstone 3

19.1 Defining the problem

19.1.1 Solution overview

19.2 Removing mutability

19.2.1 Comparing Imperative and Declarative flows

19.2.2 Moving to user-driven input

19.3 Writing Transactions to disk

19.4 Rehydrating an account from disk

19.5 Summary

Unit 5: The Pit of Success with the F# Type System

Lesson 20 Program Flow in F#

20.1 A tour around loops in F#

20.1.1 For loops

20.1.2 While loops

20.1.3 Comprehensions

20.2 Branching logic in F#

20.2.1 Priming Exercise - Customer Credit Limits

20.3 Say hello to pattern matching

20.3.1 Exhaustive checking

20.3.2 Guards

20.3.3 Nested matches

20.4 Flexible pattern matching

20.4.1 Collections

20.4.2 Records

20.5 To match or not to match

20.6 Summary

Lesson 21 Modelling Relationships in F#

21.1 Modelling Relationships

21.1.1 Composition in F#

21.1.2 Modelling a type hierarchy

21.2 Discriminated Unions in F#

21.2.1 Creating instances of DUs

21.2.2 Accessing an instance of a DU

21.3 Tips for working with Discriminated Unions

21.3.1 Nested DUs

21.3.2 Shared fields

21.3.3 Printing out DUs

21.4 Comparing OO hierarchies and Discriminated Unions

21.5 Creating Enums

21.6 Summary

Lesson 22 Fixing the billion-dollar mistake

22.1 Working with missing values

22.2 The rise of the billion-dollar mistake

22.3 Nullable Types in .NET

22.4 Improving matters with the F# Type System

22.4.1 Mandatory data in F#

22.4.2 The Option Type

22.5 The Option module

22.5.1 Mapping

22.5.2 Binding

22.5.3 Filtering

22.5.4 Other Option functions

22.6 Collections and Options

22.6.1 Option.toList

22.6.2 List.choose

22.6.3 "Try" functions

22.7 Summary

Lesson 23 Business Rules as Code

23.1 Validating business rules

23.2 Specific types in F#

23.2.1 Mixing values of the same type

23.2.2 Single Case Discriminated Unions

23.3 Combining Discriminated Unions

23.3.1 Using Optional values within a domain

23.4 Encoding business rules withmarker types

23.4.1 When and when not to use marker types

23.5 Results vs Exceptions

23.5.1 Safe functions with Results

23.6 Summary

Lesson 24 Capstone 4

24.1 Defining the problem

24.1.1 Solution overview

24.2 Stronger typing with discriminated unions

24.2.1 Reviewing the existing command handler

24.2.2 Adding a command handler with discriminated unions

24.2.3 Tightening the model further

24.3 Applying Option types with the outside world

24.3.1 Parsing user input

24.3.2 Loading existing accounts

24.3.3 Lifting Functions to support Options

24.4 Implementing business rules with types

24.4.1 Testing a model with scripts

24.4.2 Plugging our new model back in

24.5 Summary

Unit 6: Living on the .NET platform

Lesson 25 Consuming C# from F#

25.1 Referencing C# code in F#

25.1.1 Creating a hybrid solution

25.2 The Visual Studio experience

25.2.1 Debugging

25.2.2 Navigating across projects

25.2.3 Projects and Assemblies

25.2.4 Referencing assemblies in scripts

25.2.5 Debugging scripts

25.3 Working with OO constructs

25.4 Working with Interfaces

25.4.1 Creating interface implementations

25.4.2 Object expressions

25.5 Nulls, Nullables and Options

25.6 Summary

Lesson 26 Working with Nuget Packages

26.1 Using NuGet with F# Projects

26.2 Scripting with NuGet

26.2.1 Experimenting with scripts

26.2.2 Loading source files in scripts

26.2.3 Improving the referencing experience

26.2.4 Auto-generated references

26.3 Working with Paket

26.3.1 Issues with the NuGet Client

26.3.2 Benefits of Paket

26.3.3 Common Paket commands

26.4 Summary

Lesson 27 Exposing F# types and functions to C#

27.1 Why expose F# to C#

27.2 Using F# types in C#

27.2.1 Records

27.2.2 Tuples

27.2.3 Discriminated Unions

27.3 Namespaces and Modules

27.3.1 F# Namespaces in C#

27.3.2 Modules in C#

27.4 Using F# functions in C#

27.5 Summarising F# to C# Interop

27.6 Gotchas

27.6.1 Incompatible Types

27.6.2 CLI Mutable

27.6.3 Options

27.6.4 Accessibility Modifiers

27.6.5 Collections

27.7 Summary

Lesson 28 Architecting Hybrid Language Applications

28.1 Crossing language boundaries

28.1.1 Accepting data from external systems

28.1.2 Playing to the strengths of a language

28.2 Case Study - WPF Monopoly

28.2.1 Application Overview

28.2.2 Separating UI concerns from domain logic

28.2.3 Expressions at the core

28.2.4 C# Interop

28.2.5 WPF and MVVM

28.2.6 Randomness

28.3 Summary

Lesson 29 Capstone 5

29.1 Defining the problem

29.1.1 Solution overview

29.2 Plugging in a third-party NuGet package

29.3 Connecting F# code to a WPF front-end

29.3.1 Joining the dots

29.3.2 Consuming the API from C#

29.3.3 Using types as business rules in C#

29.4 Common Fields on Discriminated Unions

29.5 Polishing up F# APIs for consumers

29.5.1 Encapsulation

29.5.2 Naming conventions

29.5.3 Explicit Naming

29.6 Working with pure functions in a mutable world

29.7 Summary

Unit 7: Working with Data

Lesson 30 Introducing Type Providers

30.1 What are Type Providers?

30.1.1 Understanding Type Providers

30.2 Working with our first Type Provider

30.2.1 Working with CSV files today

30.2.2 Introducing FSharp.Data

30.2.3 Inferring types and schemas

30.3 Summary

Lesson 31 Building Schemas from Live Data

31.1 Working with JSON

31.2 Examples of live schema type providers

31.3 Problems with live schemas

31.3.1 Large data sources

31.3.2 Inferred schemas

31.3.3 Priced schemas

31.3.4 Connectivity

31.4 Mixing Local and Remote data sets

31.4.1 Redirecting type providers to new data

31.5 Summary

Lesson 32 Working with SQL

32.1 Working with SQL - the current state

32.2 Creating a basic database

32.3 Introducing the SQL Client Type Provider

32.3.1 Querying data

32.3.2 Inserting data

32.3.3 Working with Reference Data

32.4 The SQL Provider

32.4.1 Querying data

32.4.2 Inserting data

32.4.3 Working with Reference Data

32.5 What about Entity Framework?

32.6 Summary

Lesson 33 Creating Type Provider-backed APIs

33.1 Type Provider-backed APIs

33.2 Creating a tightly-coupled Type Provider API

33.2.1 Building our first API

33.2.2 An exercise in refactoring

33.3 Creating a decoupled API

33.3.1 Reasons for not exposing provided types over an API

33.3.2 Enriching a domain using F# types

33.3.3 Mapping between provided types and F# domains

33.3.4 Updating our API with a new domain

33.4 Converting to a standalone application

33.5 Summary

Lesson 34 Using Type Providers in the real world

34.1 Securely accessingconnection strings with type providers

34.1.1 Working with configuration files

34.1.2 Problems with configuration files

34.2 Manually passing connection strings

34.3 Continuous Integration with Type Providers

34.3.1 Data as part of the CI process

34.3.2 Creating a build process with a SQL Type Provider

34.4 Best Practices

34.5 Summary

Lesson 35 Capstone 6

35.1 Defining the problem

35.1.1 Solution Overview

35.2 Hooking up a SQL database

35.3 Creating a SQL data access layer

35.3.1 The SQL Repository

35.3.2 Working with SQL to retrieve account history

35.3.3 Working with reference data

35.3.4 Inserting data into SQL

35.4 Making a pluggable data access layer

35.4.1 Pluggable data access repositories

35.4.2 "Reusing" dependencies across functions

35.4.3 Handling SQL connection strings directly

35.5 Summary

Unit 8: Web Programming

Lesson 36 Asynchronous Workflows

36.1 Multi-threading and the Web

36.1.1 Threads, Tasks and Cores

36.1.2 CPU and I/O bound operations

36.1.3 The problem with concurrency

36.2 Introducing Asynchronous Workflows

36.2.1 Async workflows basics

36.2.2 More complex async workflows

36.3 Composing asynchronous values

36.4 Fork / Join

36.5 Tasks and Async Workflows

36.5.1 Interoperating with Tasks

36.5.2 Comparing Tasks and Async

36.5.3 Useful Async keywords

36.6 Computation Expressions

36.7 Summary

Lesson 37 Exposing data over HTTP

37.1 Getting up and running with ASP .NET Web API

37.1.1 Web Projects with F#

37.1.2 Using Owin Host with F#

37.2 Abstracting Web API from F#

37.2.1 Abstracting HTTP codes from F#

37.3 Working with Async

37.4 Introducing Suave

37.4.1 Modelling web requests as functions

37.5 Summary

Lesson 38 Consuming HTTP data

38.1 Using FSharp.Data to work with HTTP endpoints

38.2 HTTP.fs

38.2.1 Building requests as a pipeline

38.3 The Swagger Type Provider

38.3.1 Adding Swagger to ASP .NET Web API 2

38.3.2 Consuming Swagger APIs in F#

38.4 Summary

Lesson 39 Capstone 7

39.1 Defining the problem

39.1.1 Solution Overview

39.2 Adding Web API support to our application

39.2.1 Our first endpoint

39.2.2 Posting data to Web API

39.3 Consuming data with Swagger

39.3.1 Activating Swagger

39.3.2 Applying metadata

39.3.3 Consuming our API

39.4 Enriching the API

39.4.1 Working with Results

39.4.2 Making the API asynchronous

39.5 Summary

Unit 9: Unit Testing

Lesson 40 Unit Testing in F#

40.1 When to Unit Test in F#

40.1.1 Unit testing complexity

40.1.2 Test Driven Development or Regression Testing?

40.2 Basic Unit Testing in F#

40.2.1 Writing our first unit tests

40.2.2 Naming Tests in F#

40.3 Testing DSLs in F#

40.3.1 FSUnit

40.3.2 Unquote

40.4 Summary

Lesson 41 Property Based Testing in F#

41.1 What is Property-Based testing?

41.1.1 How to identify properties

41.2 Introducing FSCheck

41.2.1 Running Tests with FsCheck

41.2.2 Failing tests and Shrinking

41.3 Controlling Data Generation

41.3.1 Guard Clauses

41.3.2 Generators and Arbitrary Values

41.4 Summary

Lesson 42 Web Testing

42.1 Priming Exercise �Integration testing your web applications

42.2 Web Automation with Canopy

42.2.1 What is Canopy?

42.2.2 Creating our first Canopy script

42.3 Web Tests with Canopy

42.3.1 Hooking into Canopy events

42.3.2 Creating and running tests

42.3.3 Assertions in Canopy

42.4 Summary

Lesson 43 Capstone 8

43.1 Defining the problem

43.1.1 Solution Overview

43.2 Writing API tests

43.2.1 In Memory Testing

43.2.2 Example API tests in XUnit

43.3 Testing the Web API tier

43.4 Property-based tests

43.4.1 Thinking about Property Based Tests

43.4.2 Our first Property-based test

43.5 Summary

Unit 10: Where next?

Appendix A: Appendix A: The F# Community

A.1 The F# community

A.1.1 Microsoft and F# Libraries

A.1.2 Impressions of the F# community

A.2 Coding in the open source world

A.3 A real-world example of open source contributions

A.4 Summary

Appendix B: Appendix B: F# in my organization

B.1 Introducing F# to others

B.1.1 Show the positives of F#

B.1.2 Avoid dismissing C#

B.1.3 Dismiss the zero-sum game

B.1.4 Reduce the fear of learning

B.1.5 We're already productive enough!

B.1.6 Specific use cases

B.1.7 Cost / benefit analysis

B.1.8 Hiring new staff

B.1.9 Simply start using it

B.2 Introducing F# to my codebase

B.2.1 Exploratory Scripts

B.2.2 Ad-hoc processes

B.2.3 Helper modules

B.2.4 Horizontal Tiers

B.2.5 Vertical Tiers

B.2.6 Unit Tests

B.2.7 Build scripts

B.3 Summary

Appendix C: Appendix C: Must-visit F# resources

C.1 Websites

C.1.1 FSharp.org

C.1.2 Community for F#

C.1.3 F# for Fun and Profit

C.1.4 F# Weekly

C.2 Social Networks

C.2.1 Twitter

C.2.2 Slack

C.2.3 Reddit

C.2.4 The F# Mailing List

C.3 Projects and Language

C.3.1 The F# Compiler

C.3.2 Language Suggestions

C.3.3 FS Projects

C.4 Summary

Appendix D: Appendix D: Must-have F# libraries

D.1 Libraries

D.1.1 Build and DevOps

D.1.2 Data

D.1.3 Web

D.1.4 Cloud

D.1.5 Desktop

D.1.6 Miscellaneous

D.2 The F# tool-chain

D.3 Summary

Appendix E: Appendix E: Other F# Language Features

E.1 Object Oriented Support

E.1.1 Basic Classes

E.1.2 Interfaces and Inheritance

E.2 Exception Handling

E.3 Resource Management

E.4 Casting

E.5 Active Patterns

E.6 Computation Expressions

E.7 Code Quotations

E.8 Units of Measure

E.9 Lazy Computations

What's inside

  • Organized in short lessons of a few pages each
  • Quick Check questions to make sure you're on track
  • Practice as you learn with Try This exercises
  • Using the F# REPL to rapidly prototype and implement applications
  • Writing bug-free code without the need for unit tests
  • Solving complex problems using simple code
  • Creating REST-style web application
  • Working with JSON, CSV, XML, and HTML data
  • Integrating F# code with existing C# and VB .NET systems

About the reader

For intermediate C# and Visual Basic .NET developers who have heard about F# and functional programming and want to understand the benefits and use it as a part of their existing toolbox without having to throw away existing code.

About the author

Isaac Abraham is an F# MVP and a .NET developer since .NET 1.0 with an interest in cloud computing and distributed data problems. He lives in both the UK and Germany, and is the director of Compositional IT.

Manning Early Access Program (MEAP) Read chapters as they are written, get the finished eBook as soon as it’s ready, and receive the pBook long before it's in bookstores.
MEAP combo $44.99 pBook + eBook
MEAP eBook $35.99 pdf + ePub + kindle

FREE domestic shipping on three or more pBooks