Table Of ContentProgramming F# 3.0
Chris Smith
Programming F# 3.0
by Chris Smith
Copyright © 2013 Chris Smith. All rights reserved.
Printed in the United States of America.
Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.
O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are
also available for most titles (http://my.safaribooksonline.com). For more information, contact our corporate/
institutional sales department: 800-998-9938 or [email protected].
Editor: Rachel Roumeliotis Proofreader: Absolute Service, Inc.
Production Editor: Holly Bauer Indexer: Lucie Haskins
Copyeditor: Jasmine Kwityn Cover Designer: Karen Montgomery
Interior Designer: David Futato
Illustrator: Rebecca Demarest
October 2009: First Edition
October 2012: Second Edition
Revision History for the Second Edition:
2012-10-08 First release
See http://oreilly.com/catalog/errata.csp?isbn=9781449320294 for release details.
Nutshell Handbook, the Nutshell Handbook logo, and the O’Reilly logo are registered trademarks of O’Reilly
Media, Inc. Programming F# 3.0, the image of a bullfinch, and related trade dress are trademarks of O’Reilly
Media, Inc.
Many of the designations used by manufacturers and sellers to distinguish their products are claimed as
trademarks. Where those designations appear in this book, and O’Reilly Media, Inc., was aware of a trade
mark claim, the designations have been printed in caps or initial caps.
While every precaution has been taken in the preparation of this book, the publisher and authors assume
no responsibility for errors or omissions, or for damages resulting from the use of the information contained
herein.
ISBN: 978-1-449-32029-4
[LSI]
Table of Contents
Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
Part I. Multiparadigm Programming
1. Introduction to F#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Getting to Know F# 3
Visual Studio 11 4
Your Second F# Program 5
Values 6
Whitespace Matters 6
.NET Interop 8
Comments 8
F# Interactive 9
Managing F# Source Files 11
2. Fundamentals. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Primitive Types 15
Numeric Primitives 16
Arithmetic 17
Conversion Routines 19
BigInteger 19
Bitwise Operations 20
Characters 20
Strings 21
Boolean Values 22
Comparison and Equality 24
Functions 24
Type Inference 25
Generic Functions 27
iii
Scope 27
Control Flow 29
Core Types 31
Unit 32
Tuple 32
Lists 34
Aggregate Operators 39
Option 42
Printf 44
Organizing F# Code 46
Modules 46
Namespaces 47
Program Startup 48
3. Functional Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Understanding Functions 52
Immutability 53
Function Values 54
Recursive Functions 58
Symbolic Operators 60
Function Composition 61
Pattern Matching 68
Match Failure 69
Named Patterns 70
Matching Literals 70
when Guards 71
Grouping Patterns 72
Matching the Structure of Data 73
Outside of Match Expressions 74
Alternate Lambda Syntax 75
Discriminated Unions 76
Using Discriminated Unions for Tree Structures 78
Pattern Matching 79
Methods and Properties 81
Records 81
Cloning Records 82
Pattern Matching 83
Type Inference 83
Methods and Properties 84
Lazy Evaluation 85
Lazy Types 85
Sequences 86
iv | Table of Contents
Sequence Expressions 87
Seq Module Functions 88
Aggregate Operators 89
Queries 90
Query Expressions 92
Query Operators 92
4. Imperative Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Understanding Memory in .NET 98
Value Types Versus Reference Types 99
Default Values 99
Reference Type Aliasing 101
Changing Values 102
Reference Cells 103
Mutable Records 104
Units of Measure 105
Defining Units of Measure 107
Converting Between Units of Measure 108
Generic Units of Measure 109
Arrays 110
Indexing an Array 111
Array Slices 113
Creating Arrays 114
Pattern Matching 115
Array Equality 115
Array Module Functions 116
Multidimensional Arrays 117
Mutable Collection Types 119
List<'T> 119
Dictionary<'K,'V> 121
HashSet<'T> 122
Looping Constructs 123
While Loops 123
For Loops 124
Exceptions 126
Handling Exceptions 127
Reraising Exceptions 130
Defining Exceptions 130
5. Object-Oriented Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Programming with Objects 133
The Benefits of OOP 133
Table of Contents | v
Where OOP Breaks Down 134
Understanding System.Object 134
Common Methods 135
Object Equality 137
Generated Equality 139
Understanding Classes 141
Explicit Construction 141
Implicit Class Construction 143
Generic Classes 144
The Self Identifier 146
Methods and Properties 146
Properties 146
Setting Properties in the Constructor 149
Methods 149
Static Methods, Properties, and Fields 151
Method Overloading 153
Accessibility Modifiers 154
Inheritance 157
Method Overriding 158
Categories of Classes 160
Casting 161
6. .NET Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
The .NET Platform 165
The CLI 165
Garbage Collection 166
Interfaces 168
Using Interfaces 169
Defining Interfaces 170
Object Expressions 171
Object Expressions for Interfaces 172
Object Expressions for Derived Classes 173
Extension Methods 174
Extending Modules 175
Enumerations 176
Creating Enumerations 176
Conversion 178
When to Use an Enum Versus a Discriminated Union 178
Structs 179
Creating Structs 180
Restrictions 182
vi | Table of Contents
When to Use a Struct Versus a Record 182
Part II. Programming F#
7. Applied Functional Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Active Patterns 185
Single-Case Active Patterns 187
Partial Active Patterns 187
Parameterized Active Patterns 189
Multicase Active Patterns 190
Using Active Patterns 192
Using Modules 195
Converting Modules to Classes 195
Intentional Shadowing 198
Controlling Module Usage 200
Mastering Lists 201
List Operations 202
Using Lists 203
Tail Recursion 205
Understanding the Stack 206
Introducing Tail Recursion 208
Tail-Recursive Patterns 210
Programming with Functions 214
Partial Function Application 214
Eliminating Redundant Code 215
Closures 216
Functional Patterns 218
Memoization 218
Mutable Function Values 220
Lazy Programming 221
Functional Data Structures 223
Functional Set 223
Functional Map 225
8. Applied Object-Oriented Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
Operators 227
Operator Overloading 227
Indexers 229
Adding Slices 231
Generic Type Constraints 234
Delegates and Events 237
Table of Contents | vii
Defining Delegates 238
Combining Delegates 240
Events 241
Creating Events 241
The Event<_,_> Class 243
The Observable Module 244
Creating .NET Events 248
9. Asynchronous and Parallel Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Working with Threads 252
Spawning Threads 253
The .NET Thread Pool 254
Sharing Data 255
Asynchronous Programming 259
Asynchronous Workflows 262
The Async Library 263
Async Operations 268
Custom Async Primitives 269
Limitations 270
Parallel Programming 271
Parallel.For 271
The Array.Parallel Module 272
Task Parallel Library 273
Primitives 274
Concurrent Data Structures 278
10. Scripting. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
F# Script Files 284
Directives 284
General Directives 285
F# Script-Specific Directives 286
F# Script Recipes 288
Colorful Output 288
Producing Sound 289
Walking a Directory Structure 289
Starting Processes Easily 290
Automating Microsoft Office 291
11. Data Processing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
Indexing 296
The Index Data Structure 296
MapReduce Processing 299
viii | Table of Contents