Sie sind auf Seite 1von 136

The F# Survival Guide

by John Puopolo with Sandy Squires Introduction


Welcome to The F# Survival Guide. The purpose of this Web book is to provide a solid foundation and pragmatic introduction to F# programming and its functional underpinnings. I wrote this book with the intent that it is the first book you read in your F# journey. Along these lines, this book covers the entirety of the core F# language, as available November 2009. It covers all of the documented (and some of the less documented) concepts, keywords, constructs, types, and language symbols. In addition, I have tried to provide short examples that capture the essence of the topic at hand, while at the same time discussing real-world impacts. My hope is that after reading this book, you will be able to develop non-trivial applications using F#, and will be able to readily extend your learning via additional resources.

Why This Book?


While there are several books in print, and some Web-based resources for learning F#, I have not found a single one that's altogether clear, concise, and easily digestible by mainstream developers. Few, if any, of these resources takes a bottoms-up approach, methodically building up a conceptual and practical framework that builds skills and confidence in a systematic way. Additionally, most of the F# materials that I've read are to some extent academic, with a bent towards describing F# in terms of esoteric constructs (check out the Maybe monad on the Web for a good dose of newbie confusion!). In my (humble) opinion, much of the existing material doesn't resonate naturally with OO application developers. These are the issues that I've tried to address with this book. Also, whenever I read technical books, I ultimately have questions that roll through my head as I go. The books I tend to love anticipate my "rolling questions" and answer them quickly and clearly. I will do my best to anticipate your rolling questions and answer them in kind. I've also made it a point to keep the chapters relatively short, covering one or two related topics at a time. Lastly, I tend to dislike books that introduce new concepts and syntax without first establishing a solid foundation. One of the goals I have for this book is to wait until I've covered a topic before using it in examples, etc. I get frustrated when books throw in a new concept in the middle of an example it's very distracting and usually takes away from the point that the author is trying to make. Therefore, I will use data structures, syntax and concepts only after we've discussed them. Because certain language features are so highly interconnected, this may not always be possible; however, I think we can go a long way here. Instead of lamenting over the dearth of palatable materials and complaining about what I don't like (that's too easy), I've decided to do something about it and contribute to the development community as best I can. I've chosen this particular topic because I feel quite strongly that functional programming will play prominently in the next decade of computing. Why? Two words: multicore processors. In order to increase compute speeds and throughput cycles, technology manufacturers such as Intel, AMD, Dell, HP, etc. have taken to shipping computers with multiple CPUs and CPUs with multiple cores. Given this trend, it is not unreasonable to assume that near-future desktops will contain 8, 16, 32 and more cores. Beyond the desktop, there is "the cloud", with virtually unlimited computing resources available. In order to take advantage of all this computing power, we developers will need to think differently about how we design and write our software. I feel this way because writing concurrent, multi-process, multithreaded, asynchronous applications is already famously difficult, and it will only become more so with the continued scale and adoption of compute-rich hardware. By learning functional programming concepts in the context of a rich, fully-supported language and tool chain, and learning how to apply these properly, you are well on your way to preparing for the next generation of software development.

Intended Audience
This book is intended for professional software developers, students of computer science, and advanced enthusiasts who want to gain a foundation in functional programming and fluency in F#. It will be especially useful to those coming from a mainstream imperative/OO background. I have found that the "functional guys" love to explain things in mathematical and sometimes obtuse terms. I don't think that it's intentional it stems from what the Heath brothers call "the curse of knowledge" in their (wonderful) book Made to Stick. Coming from an imperative/OO background myself, I know how "we" think about problems, hopefully explaining things in terms that are somewhat familiar and comfortable to you. I assume that you have developed software in the past, and have a working understanding of fundamental programming concepts such as variables, conditional structures, expressions, loops, collections, linked lists, etc. You will have programmed in C, C++, Python, etc. I also assume that you are familiar with at least one object-oriented language such as C++, C#, Java, etc.

Lastly, to get the most out of this book, you should be familiar with core .NET programming concepts and libraries.

About the Authors


John Puopolo has been developing software professionally for over 20 years. He started developing on IBM AS/400s in C and quickly moved to the then-new PC platform and Windows (3.1). Over the years, John has developed enterprise software for financial institutions, consumer applications, mobile carriers and handset OEMs, enterprise search, GPS and LBS systems, and most recently, leads a team in the design and development of a next-generation ad network. He has practical and professional experience developing in C, C++, Java, Python, C# and F#. He lives outside of Boston, MA with his wife Jill, three daughters, and a funny little dog named Sugar. For feedback and comments, contact John at johnp@ctocorner.com (mailto:johnp@ctocorner.com) or visit us at www.ctocorner.com. Sandy Squires is a software consultant with more than 20 years experience. He has worked on developing systems of all different sizes - mainframe, minicomputer, PC, mobile, and embedded in more than 20 different computer languages. Sandy enjoys working on scientific and applied engineering systems, especially designing algorithms for digital signal processing, computational geometry, and machine vision. He resides in the greater Boston area with his wife, Susan, three daughters, a dog named Chaos, and two cats.

Useful Links and Resources


While there are many F# resources on the Web, they are at different stages of maturity and complexity. As you are coming up to speed, I recommend sticking to a small set of recognized sites, and branching out as you become more comfortable with the material. In this spirit, I recommend the following sites: Microsoft F# Developer Center (http://msdn.microsoft.com/en-us/fsharp/default.aspx) Don Syme's Blog (http://blogs.msdn.com/dsyme/default.aspx) (creator of F#) F# Language Reference at MSDN (http://msdn.microsoft.com/en-us/library/dd233181(VS.100).aspx) Real World Functional Programming (http://www.functional-programming.net/) by Tom Petek F# Programming on Wikibooks (http://en.wikibooks.org/wiki/F_Sharp_Programming) CTO Corner, The F# Survival Guide (http://www.ctocorner.com/fsharp/book/default.aspx) In addition to these resources, we will keep the blog up-to-date with new articles, code samples, etc. and commentary. We hope this will be especially useful as Visual Studio 2010 nears commercial release. You can find our blog at the CTO Corner at www.ctocorner.com/blog (http://www.ctocorner.com/blog) .

Chapter 1 Introduction to Functional Programming


Introduction
There are many ways to examine problems and model their solutions. In software, we tend to look at problems through the lens of our experiences and the tools that we have at our disposal. In other words, our experiences and the tools we know influence how we approach solving problems. For example, in the days of structured programming, we solved many problems using procedural decomposition and subroutines, focusing on internal cohesion and loose coupling. Building on these successful techniques, we transitioned to modeling solutions using objects and object-oriented techniques, further encapsulating imperative code and its data. While object-oriented design and object-oriented programming will continue to play a significant role in years to come, I believe we are facing challenges that require new ways of thinking and new ways of implementing solutions. For example, massive computing power via multi-core architectures and cloud computing will make developing concurrent systems and parallel algorithms a virtual necessity. Functional programming provides us with many of the tools and technique we need to make this a reality. Additionally, functional programming gives us new ways of developing scalable systems that are easy to debug and test.

What is Functional Programming?


Functional programming is a specific way to look at problems and model their solutions. Pragmatically, functional programming is a coding style that exhibits the following characteristics:
power and flexibility we can solve many general real-world problems using functional constructs simplicity most functional programs exhibit a small set of keywords and concise syntax for expressing concepts suitable for parallel processing via immutable values and operators, functional programs lend themselves to asynchronous and parallel processing Functional programming treats computation, e.g., running a program or solving a numeric calculation, as the evaluation of functions. Not surprisingly, in dealing with functional programming, we will use the term function quite often and in many contexts. So, before we continue, let's make sure we understand what a function is:

A function is fundamentally a transformation. It transforms one or more inputs into exactly one output.
An important property of pure functions is that they yield no side effects. This means that the same inputs will always yield the same outputs, and that the inputs are not changed as a result of the function. This idea of "no side effects" is one (of several) that makes functional programming particularly attractive when writing multi-process and multithreaded systems. As we go through the book, I will point out and explain the key concepts that make functional programming attractive for solving certain types of problems.

Purely Functional?
Some programming languages are "purely functional languages." This means that they follow strict functional rules, e.g., no imperative looping constructs and no implicit way to introduce state changes. For example, Haskell, a pure functional language, disallows state changes and side effects altogether. Programs written in pure functional languages are almost solely made up of functions that accept arguments and return values. Unlike imperative and object-oriented languages, they allow no side effects and use recursion instead of loops for iteration. Languages like Haskell are often criticized as being too extreme in not allowing side effects, giving them limited penetration in mainstream development environments. Operations such as reading a file become awkward to code in a language where no side effects are allowed. In contrast, impure, multi-paradigm languages such as F# discourage side effects and imperative constructs, but make them available alongside their functional brethren. From the abstract mathematical theory of functions comes a variety of interesting concepts that have broad application and use in functional computing. For example, functions can take other functions as arguments, and functions can return other functions as results. This ability results in flexible and powerful mechanisms that enable us to implement ideas simply and elegantly ideas that are difficult to express in non-functional languages. We explore these mechanisms throughout the rest of the text.

Functional vs. Imperative


We can think of imperative programming as writing code that describes in exacting detail the steps the software must take to execute a given computation. These steps are generally expressed as a combination of statement executions, state changes, loops and conditional branches. In contrast, functional programming looks at a program as a set of nested functions one "outer" function (the program) calling one or more "inner" functions to calculate a value to be returned as the result of the program. Functions take arguments and calculate return values, but do not maintain a "state of the program" per se.

Most modern programming languages support sufficient logic and data storage as to make them Turing complete (http://en.wikipedia.org/wiki/Turing_completeness) . This means that in principle they can be used to write programs to solve any "computable" problem. F# is also a Turing complete language. The crux of choosing a language is not then one of capability, but of inherent applicability. F# offers some advantages over other languages when working on certain classes of problems. Some general strengths of F# are as follows: The signal-to-noise ratio is high. F# is economically expressed, e.g., favoring whitespace over other grouping symbols. As a result, your code ends up being quite succinct. Powerful matching logic based not only on Boolean values but the "shape" and type of the data. Built-in support for "lazy evaluation" of expressions. Built-in support for writing thread-safe and asynchronous applications very simply via asynchronous workflows. To help make things a little more concrete, and whet your appetite for the material to come, let's consider a few examples that help contrast how we'd look at and solve the same problem from the imperative vs. the functional perspective.

Example 1: Filtering a List


Let's suppose we have a list of 10000 employee records in a list, and we want to find all the employees who salary equals or exceeds 100,000 dollars. Taking the imperative approach, we would most likely write a for- or while-style loop, examining each employee's salary to see if it met our criteria. For each employee meeting the criteria, we would append the record to a growing list of matches. As you can see, we delineate each and every step in detail. In contrast, from a functional perspective, we would describe this solution as applying a filter (function) to a list with the goal of producing a new resulting list.

Example 2: Downloading Files Asynchronously


Asynchronous and parallel programming are difficult to do and even more difficult to get right. For example, to asynchronously download HTML pages from the Web via imperative languages requires us to create HTTP channels, issue asynchronous calls, write completion routines, and manage failures. Depending on the implementation, we may need to also manage our own threads. This results in a lot of complex, error-prone code. While we can't escape having to perform these tasks in some way, we can manage them much more succinctly and rigorously in functional languages by structuring and sequencing the calls using a concept called workflows.

Example 3: Customizing Algorithms


A classic problem that functional languages address elegantly is that of arbitrary value comparison. When your program needs to sort or compare values, it needs a mechanism to determine whether two values are "equal" or if one value is "less than" the other. When using naturally ordered elements, such as numbers or letters, the natural ordering applies. In many business-style programs, however, we need to compare elements that have no natural ordering, e.g., Employees, Automobiles, Tickets, Movies, Concerts, etc. In these types of applications, it's extremely convenient to supply a comparison or sorting function that can be subsequently executed against two elements. This is one of the most powerful capabilities of functional programming the ability to not only pass and return simple values, but the ability to pass and return functions. To solve this problem in a functional language, you merely pass the main comparison function a "sort function" that it can use to compare two elements. Depending on the context of the application, or the types being sorted, the program can pass along different "sort functions" without changing the main routine whatsoever. Functional languages tend to exhibit this compositionality in most aspects of their design and, ahem, function. To address this problem in traditional imperative languages, we'd need to resort to function pointers or similar constructs. Again, this is possible to do, but not as clean or elegant as it can be. We should note here that C# now ships with some functional constructs, including anonymous functions and lambda expressions, which help to elegantly address this type of problem.

Example 4: Creating Infinite Sequences


There are certain data sets that are "naturally infinite", e.g., the set of all prime numbers, making their complete calculation impossible. Functional languages employ mechanisms such as lazy evaluation and delayed computation to make infinite sets both representable and efficiently computed in on-demand fashion. Again, while you can accomplish the same things in non-functional languages, the imperative implementations tend to be "less natural" and more convoluted.

What Problem Spaces are Naturally Addressed by Functional Programming?


Growing up, I'd occasionally help my dad fix things around the house, paint, etc., and from the many things he taught me, "the right tool for the job" stands out clearly. When faced with a problem, you need to consider what you have in your "toolbox" and decide the best way to solve it. Certain problems can be solved easily with a hammer, whereas with others you need a saw. You need to apply the same thought process to choosing programming paradigms and the languages that support them. Functional programming is appropriate for applications that exhibit one or more of the following characteristics: require significant computation (compute-bound) as they can be parallelized easily, are themselves parallel in nature, can benefit from asynchronous calls, need to be provable, or require sophisticated pattern matching. This means that functional programs are not generally applicable to typical line-of-business applications that deal with objects and their state over time; however, there may be portions of those programs, e.g., portfolio basket optimization for fixed-income securities, that would benefit greatly from

using functionally-based libraries. We typically see functional programming applied to image processing, machine algebra, lexing and parsing, artificial intelligence, and data mining.

Why Should I Care About Functional Programming?


While you can develop concurrent, scalable and asynchronous software without embracing functional programming, it's simpler, safer, and easier to use the right tool for the job. Functional programming enables you to take advantage of multi-core systems, develop robust concurrent algorithms, parallelize compute-intensive algorithms, and to readily leverage the growing number of cloud computing platforms. In addition, if you've not already explored non-imperative programming, it's a great way to expand your problem solving skills and your horizons. The new concepts that you'll learn will help you to look at many problems from a different perspective and will help you to become a better and more insightful OO programmer. A note of caution: I am not here to convince you how wonderful functional programming is, or how it will change your life. It is a tool - nothing more, nothing less - that helps to solve a certain class of problems. In this book, we will explore and explain these types of problems, and point out why functional programming applies. We will explore functional concepts in depth in Chapter 8, Functions and Functional Concepts. To build up to that, we will first study F#'s syntax, primitive data types, control flow structures, loops, and basic collections. Note: Each chapter ends with a What You Need to Know section, which is the thumbnail summary of the topics covered. Here's one now

What You Need to Know


Functional programming is a way to implement software solutions. We contrast it with imperative and OO programming. Functional programs implement computation as nested and successive evaluation of functions. Functional programming languages discourage side effects. Pure functional languages don't allow them. Pure functional programming languages like Haskell can be difficult to use. F# is an impure functional or multi-paradigm language and has flexibility when you need it. By encouraging functional programming principles, F# makes writing concurrent, scalable, asynchronous applications simpler than writing these same applications using imperative and/or OO languages.

Chapter 2 Introduction to F# & Essential Tools


Introduction
In this chapter, we introduce the F# language and learn how to get our first program up and running. In doing so, we will discuss the basic rules around F# program structure and the essential tools you will need to develop rudimentary applications. As we progress through the book, and our experience grows, we will delve more deeply into code examples, tool examples, etc.

Overview of F#
F# is a strongly typed, first-class .NET programming language designed by Don Syme (http://research.microsoft.com/enus/people/dsyme/) and others at Microsoft Research (http://research.microsoft.com/en-us/default.aspx) . It has its origins in the ML approach to language design (http://en.wikipedia.org/wiki/ML_programming_language) and is a close relative of OCaml (http://en.wikipedia.org/wiki/OCaml) . While billed primarily as a functional language, F# is in actuality a multi-paradigm language. This means that it supports imperative, OO, and functional styles of programming. A fully supported .NET language in its own right, F# interoperates naturally with code written in other .NET languages such as C# and VB.NET. F# is available as a free download (http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/release.aspx) , and will be integrated into Microsoft Visual Studio 2010. You can find the most recent F# Language Reference here (http://msdn.microsoft.com/enus/library/dd233181(VS.100).aspx) . For this book, I started with the September CTP version 1.9.6.2 and transitioned to the October CTP version 1.9.7.8. All of the code has been tested against 1.9.7.8. Please consult the language reference for the basic rules and regulations of F#, e.g. the rules around defining a valid symbolic name, etc.

F# Program Structure
You create F# programs using a standard text editor or IDE. With an IDE such as Visual Studio 2008 or Visual Studio 2010, you get the benefit of syntax highlighting, IntelliSense, etc. As with other programming languages, F# adheres to a specific set of syntax and structural rules, uses a well-defined set of keywords, etc. We will cover the core keywords, syntax, and structure of F# programs starting in this chapter, and will continue to build on this knowledge throughout the rest of the text.

#light
Due to its heritage, F# is compatible with OCaml. This means that you can write F# programs that are fully compliant with OCaml's syntax and semantic rules. Many developers, however, find OCaml's syntax to be quite "chatty" or "heavy"; therefore, F# supports a more streamlined programming syntax and semantic, known as "light" mode. You instruct F# to adhere to this light mode by placing the #light directive at the top of each of your F# program files. For all intents and purposes, all of the F# programs that you encounter and write will use the #light directive. If you fail to use place the #light directive at the top of each of your F# program files, you will default to OCaml-compatible "verbose mode." This will require the use of particular keywords and symbols to terminate expressions, etc. In the spirit of keeping things streamlined and to the point, we will not cover the verbose mode syntax in this book, nor will we cover structures and/or symbols that are in F# solely to support OCaml compatibility. When you write F# programs and use the #light1 directive, whitespace becomes significant to the structure and execution of the program. Whereas other languages, e.g. C#, use braces or other symbols to group compound statements, F# uses whitespace indentation for the same purpose2. Code that is vertically aligned by whitespace indentation is considered to be semantically related. Python programmers will feel right at home with this concept. Note that F# does not recognize TAB as a valid whitespace character when used for aligning code blocks in #light mode. This means that you need to use spaces to align your code. Before you groan too loudly, read the next two points: 1. 2. The number of spaces doesn't seem to matter. You can use 1 or more. I typically use 4, which matches the equivalent TAB. When working in a Visual Studio F# Project (more on this shortly), the IDE converts TAB to spaces automatically. So, you can use the TAB key to align your code, and Visual Studio does the right thing in terms of ensuring your F# files have the right kind of whitespace. I assume you can set up your editor of choice to replace TABs with spaces as well.

Whitespace Matters

Comments

F# provides several different types of comment structures: single line comments, multiline comments and document (doc) comments. Let's take a look at each type below.

Single Line Comments


Single line comments begin with a //. Everything following the // is considered to be a comment. The comment extends to the end of the source code line.
\\// This is a single-comment. Everything from the start is treated as a comment.

Multiline Comments
Multiline comments begin with (* and end with *).
\\(* This is a multiline comment with only one line *) (* This is another multiline comment *)

Document (Doc) Comments


Doc comments start with /// and are used to embed comments in the code from which XML or HTML documentation can be produced automatically. These comments are normally placed before the definitions of functions, data types, classes, discriminated unions, etc. We will discuss each of these structures in depth in future chapters.
\\/// This is a doc comment that can be converted to useful documentation.

Keywords
F# has a small set of reserved keywords. These keywords cannot be used as value or identifier names, as they have special meaning to the compiler:
abstract base delegate downto exception for in internal member new open public struct try val with and begin do elif extern fun inherit lazy module not or rec then type void yield as class done else false function inline let mutable null override return to upcast when assert defaul downcast end finally if interface match namespace of private static true use while

Table 2.1: F# reserved keyword

The following keywords are part of OCaml, and should be treated as reserved in F#:
asr lsr land lxor lor mod lsl sig

Table 2.2: OCaml reserved keyword

And, for completeness, we note that the keywords below are not currently used, but are reserved for future use:
atomic const eager functor mixin protected trait break constraint event global object pure virtual checked constructor external include parallel sealed volatile component continue fixed method process tailcall

Table 2.3: F# reserved keyword not currently used

Don't worry that you may not understand most (or any!) of these keywords at this point. We will explore each of them throughout the course of this book. For each keyword, we will discuss its use in F# and how it applies to functional programming in general.

Statements vs. Expressions


In many programming languages, there is a sharp distinction drawn between statements and expressions. It is an important distinction, since it dictates where you can use given programming structures, and how these structures are ultimately evaluated. Let's come up with working definitions that we can rely on throughout the text:

Statements
Statements are lines of code that impart a directive they "do" something. Statements do not evaluate to a value, and cannot be passed into functions as parameters. F# has no statements.

Expressions
Expressions are lines of code that evaluate to a value, e.g.:

let x = 100 x

In F#, every program construct is an expression. This means that all program constructs evaluate to a value of a concrete data type. The fact that all constructs in F# are expressions is important, because it influences the way we write our programs. If you do not understand the difference between statements and expressions, re-read this small section until you are comfortable with the difference. The take-away here is that F# has no statements, only expressions. Note that one oddball case that comes up in the statement/expression scheme of things concerns let. By itself, let does not always evaluate to an expression, e.g., it cannot be used as the last line of a function. In these cases, you must supply the let's symbol, e.g., x in the example above.

Accessing Existing .NET Types


In some of the examples in this book, and certainly in real-world programs, you will need to access functionality present in external libraries and modules. To gain access to the functionality contained in these libraries and modules, we use the F# keyword open.

open
The open keyword (like the C# using statement, brings an existing namespace into scope. This affords us the convenience of using the namespace's interfaces, classes, etc. without having to fully qualify the names each and every time. The open statement is called an import statement, and takes the following form:
open module[3]-or-namespace

Here, namespace must be a valid .NET namespace either a built-in namespace or one of your creation (or third-party creation). Note that to gain access to a given namespace, you must have a reference to the proper .NET type-container such as a DLL, e.g., System.Windows.Forms.dll. If the IDE reports that it cannot resolve an open expression, make sure you have a reference to the DLL containing the namespace you're trying to open. Let's look at an example. To gain access to the classes in the .NET System namespace, we can either fully qualify the name, e.g., System.Environment, or we can open the System namespace and use the Environment class without qualification. The following example demonstrates the difference:
let[4] fpath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop) open System let fpath2 = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)

Via open System, we get access to System's publicly available types, classes, interfaces, etc. without needing to fully qualify their names. The open declaration makes the names available in the code that follows the declaration, up to the end of the enclosing namespace, module, or file. When you use multiple import declarations, they should appear on separate lines. There is no special line-termination character.

Dealing with Ambiguity


There are times when you open multiple namespaces, and the same name (function, type, etc.) appears in more than one of them. Unfortunately, the F# compiler does not emit an error or warning when ambiguities or name clashes occur. Instead, F# uses a "last one wins" strategy, giving preference to the more recently opened module or namespace. As of this writing, the MSDN documentation suggests "being careful" when using namespaces that could export colliding names. If you do open namespaces that create ambiguity, you can explicitly specify the construct you want by spelling out the entire, qualified name. When in doubt, be verbose!

Namespaces Open by Default


There are certain namespaces that are so common that F# makes them available automatically. These are as follows:
Microsoft.FSharp.Core

Microsoft.FSharp.Core.Operators Microsoft.FSharp.Collections Microsoft.FSharp.Control Microsoft.FSharp.Text

Contains basic F# type definitions for built-in types such as int and double. Contains core arithmetic operations such as + for addition and * for multiplication. Contains immutable collection classes such as List and Array. Contains types for control constructs such as lazy evaluation and asynchronous workflows (covered later).

Contains functions for formatted IO, such as the printf function. Your F# programs can use the publicly available constructs from these default libraries without using an open statement and without fully qualifying their names.

Tools of the Trade


After downloading and installing F#, you should see a menu item under the Windows Start menu that has the title Microsoft F# CTP 1.9.7.8. Under this menu item, you will find the core F# tools.

F# Interactive (Console)
F# ships with an interactive, command-line style interactive programming window called the F# Interactive Console. The console executable, fsi.exe, lives under the F# installation bin directory. On my machine, the full path to the console is:
C:\Program Files\FSharp-1.9.7.8\bin\fsi.exe

This console enables you to enter and execute F# expressions, and receive feedback. The F# Interactive Console runs standalone; therefore, you do not need to have Visual Studio running to launch it. Using the F# Interactive Console is a great way to explore the F# language, interactively test blocks of code, incrementally prototype algorithms, etc. You can, and I suggest you should, use the F# Interactive Console to run and test all of the examples in this book. To ensure that your F# environment is up and running correctly, click the Windows Start menu, find the Microsoft F# CTP folder (see above screen shot - your CTP version may be newer than mine or you may be working with the final release) and click on the F# Interactive (Console) menu item. You should see the following console window appear:

This is the F# Interactive Console Window. The normal prompt is a greater than symbol ( >), which indicates that F# is ready to accept a new expression. Let's use a simple example to see how this works. Any programming book worth its salt includes a "hello, world!" program, so in the venerable tradition of Kernighan and Ritchie (K&R), let's make sure F# is installed correctly by entering in the following line of F# code in the F# Interactive Console:
printfn "hello, world!";;

Note that you terminate expressions in the F# Interactive Console using a pair of semicolons (;;). F# will respond by printing the line of text, and by providing some feedback, as shown in the following screen shot:

Don't worry too much about the feedback. Here F# is telling us that the expression it just evaluated (the "it") returned F#'s equivalent of void (unit, also expressed as ()). We'll cover these concepts shortly. Note that F# is a case-sensitive language, i.e., case is significant. You cannot, for example, enter PRINTFN "hello, world!";;. F#

will produce an error letting you know that PRINTFN is not a recognized command or function: error FS0039: The value or
constructor 'Printfn' is not defined.

While using the F# Interactive Console, it's easy to forget to terminate your expressions using ;;.If you forget to do this, here is what you'll see:

Notice the F# responded by outputting a dash (-), indicating that it's waiting for more input. At this point, you can enter another F# expression, or terminate the current expression using ;;. If you enter another expression, F# adds this to the current "expression set". It continues to add expressions to its expression set until you terminate the set using ;;, at which point it will execute all the expression in the set at once. In the following screen shot, we entered 2 expressions for F# to evaluate.

The F# Interactive Console has a handful of directives that it understands. For a list of these directives, enter #help;; at the command prompt (>), as shown below:

The first three entries are used to access pre-existing libraries and assemblies. For example, if you want to access .NET libraries that provide Web access, you need to access the System.Web.dll. This DLL is not available by default; therefore, to gain access to it in the F# Interactive Console, you would enter the following command:

#r "System.Web.dll"

Note that the double quotes surrounding the library name are necessary for this command to work properly, as shown in the following screen capture:

At the moment, there's nothing useful we can do with this library, since we don't have enough F# syntax as context. I just wanted you to get a feel for what these command do. We'll see how to leverage the .NET class libraries in gory detail in Chapter 13. We use the #path command to extend the search path that F# uses in order to find libraries and assemblies, and the #load command to load an F# file into memory, compile it, and make it available for use. We can use the #time command to activate basic profiling for F# expressions, measuring their execution times For example, Issue the #time "on" command to activate profiling, and #time "off" to deactivate it. We use both in the following example:

As you can see from the output, activating timing causes the F# Interactive Console to output CPU time and generation-centric garbage collection information. At the time of this writing, there is no way to use the F# Interactive Console to get help on a keyword or built-in function. If you want to influence how the F# Interactive Console behaves, you can launch it yourself and provide command-line switches. For example, if you want to launch the console so that standard output is suppressed, provide the --quiet switch, as in the following example:

For a full list of all the switches available, enter fsi --help on the standard command line. Unfortunately, once the F# Interactive Console is up and running, there doesn't seem to be a way to reset its environment to eliminate all bound references, etc. When I need to do this, I generally close my current session and start anew. When you enter something the F# does not understand completely, it will display an error message in red text, as shown below:

You will receive error output even if you are running in quiet mode; however, that is the extent of the console's debugging capabilities. The F# Interactive Console does not have a provision for debugging F# code snippets. To debug scripts or programs, you need to use the full Visual Studio IDE and debugger. Once you're done using the F# Interactive Console, you can exit by closing the console window or by executing the #quit;; command.

F# Interactive Console and Visual Studio


If you have Visual Studio installed, and you install F#, F# will integrate with Visual Studio by adding a set of project templates and a handful of new menu items. These changes enable you to create F# solutions and projects, and to use the Visual Studio IDE and the F# Interactive Console in unison. To display the F# Interactive Console in Visual Studio 2008, go the main menu and select View -> Other Windows -> F# Interactive. One convenient feature the integrated console window supports is the ability for you to reset its environment: right-click your mouse over the window and select Reset Session from the context menu. The best and easiest way to work with the integrated console is to develop code in the IDE editor, select it, and then right-click the mouse over the selection to bring up the editor's context menu. If you select the menu item Send to Interactive, Visual Studio will send the selected code to the integrated F# Interactive Console, and will automatically append a ;; to the end of the entire block, which you use to terminate a set of statements in the console window. In response, the console will execute the F# code and provide immediate feedback. Note that when working in the F# Interactive Console directly (vs. working in the IDE and using Send to Interactive), you must explicitly terminate each logical expression with ;; (two semicolons). A logical expression can span more than one line. This means that you can have several F# sources lines terminated by a single ;; pair. Throughout this text, we will see examples of single-line and multi-line expressions used in the F# Interactive Console. When working outside of the F# Interactive Console, a normal newline character terminates F# expressions implicitly you do not need to use ;;, e.g.,. when you're building an F# application in the IDE and build it to produce a DLL or EXE. As you start using the F# Interactive Console, you will notice that for each expression/program you enter, F# will provide feedback. This feedback will consist of all expression/program output plus F#'s evaluation of the data types involved. I found (and still sometimes find) F#'s typing signatures a little confusing to decipher, so I will spend some time explaining what the type signatures mean as we encounter them.

F# Projects in Visual Studio


After installing F#, you will find that Visual Studio offers a new set of project templates. This is what the New Project window looks like on my machine after installation:

With the current CTP version of F# (1.9.6.16), Visual Studio offers the following project types: F# Application. Select this type of project to create a command-line (console) application (EXE). F# Library. Select this type of project to create an F# library. A library is a DLL that can be included in other .NET projects. When you select this project type, the resulting solution will contains two files: Module1.fs. This is the default source file for the library that will be compiled into the output DLL. Scritp.fsx. This is a "script" file that you can use to work with F# interactively. The code that you enter into this file is not included in the final output DLL. F# Tutorial. Select this type of project to create an F# source file that illustrates key features of the F# language. This project creates an EXE. We will wait until the chapter on functions (Chapter 8) to provide full IDE-based examples, since at this point you will be prepared to write full, simple F# programs.

The F# Compiler
When you use Visual Studio to build an F# application, it executes the underlying F# compiler, fsc.exe. On my machine, the compiler can be found here:
C:\Program Files\FSharp-1.9.6.16\bin\fsc.exe.

Like any other .NET compiler, the F# compiler supports a variety of configuration options. For more information about the F# compiler and its options, please see the F# compiler documentation (http://msdn.microsoft.com/en-us/library/dd233174(VS.100).aspx) on MSDN.

Printing Values using Printf


As you work through examples in this book and on the wild Web, you will be displaying values to the F# console a good deal of the time. Be advised that F# ships with a module called Printf (http://msdn.microsoft.com/en-us/library/ee340484(VS.100).aspx) that enables you to display values in a variety of formats. For those of you coming from a C# or VB.NET background, check out Printf.sprint and Printf.kprintf (http://msdn.microsoft.com/en-us/library/ee370560(VS.100).aspx) .

What You Need to Know


F# is a multi-paradigm language whose main thrust is to support functional programming constructs. F# is a fully supported .NET language capable of interoperating with other .NET languages. F# is based on a language called OCaml. You can use OCaml syntax to write F# programs; however, OCam'l's syntax is verbose. F# supports a less verbose "light" syntax that most developers favor. To ensure you are using the light version, you must place the #light directive at the very top of each of your F# source code files. We use the light syntax in this book. The primary syntactical construct in F# is an expression, i.e., something that evaluates to a value. F# does not have statements, per se. You can use the F# Interactive Console ( fsi.exe) to explore F#. We recommend you use the console to experiment with simple expressions while learning the F# language. The F# Interactive Console can be run stand-alone, integrated with Visual Studio 2008, or both. F#'s compiler is called fsc.exe. Similar to compilers for most other languages, it has a variety of options that you can use to control how it operates. Using Visual Studio, you can create console applications, libraries (DLLs) and applications (EXEs) with F#, just like you would do with other .NET languages. You can even link and execute modules compiled from F# seamlessly with modules written in other .NET languages.
[1]

If you are not using the #light directive, you are defaulting to using full OCaml syntax, which obviates the need for significant whitespace, but imposes the burden of semantically significant keywords. [2] Python programmers will feel at home here. [3] In F#, a module is a way to package code. It is a grouping of F# code, such as values, types, and function values. Grouping code in modules helps keep related code together and helps avoid name conflicts in your program. We will cover modules later. [4] We will cover let shortly. It simply introduces a new variable.

Chapter 3 Numeric Types & Operations


Introduction
In this chapter we will start to discuss data types. To keep things simple (F# has many data types, which we will explore in detail), we will focus our discussion on numeric types only. This will provide a good introduction to F#'s typing system, and will provide a context for discussing type-related constructs.

What are Data Types?


Data types provide a way for us to tell F# how to treat and handle given data elements. When you associate an element with a data type, you're defining the range of values that the element can assume and the operations in which the element can participate. From the perspective of data types, programming languages are divided into two broad categories: Dynamically-typed, a.k.a., weakly typed, languages Statically-typed, a.k.a., strongly typed languages While a discussion of the pros and cons of each category is beyond the scope of this book, we need to note that F# is a strongly typed language. This means that every data element, value, and expression has a valid, well-known type that is fixed when the source code is compiled, i.e., its type cannot vary at run time. Even though F# is a strongly typed language, F# source code only sometimes requires explicit type declarations for symbols. This is because F# employs type inference (http://msdn.microsoft.com/en-us/library/dd233180(VS.100).aspx) , which is a mechanism by which F# deduces data types based on implicit contextual information in the source code.

Numeric Literals
Numeric literals in F# are just like numeric literals in most other languages literal numbers like 4 and 7.1. You can tell exactly what type a numeric literal is from how it is written. In most cases, the letter(s) at the end of the number will determine the type. F# can represent individual bytes, small integers, large integers, floating point values of varying precision, etc. It even supports direct expression of Decimal and Big number types found in .NET languages, but not available in many other languages. Table 3.1 below summarizes each of F#'s numeric data types, along with the F# keyword you can use to define them. Also shown is the type symbol that you can use to force a literal to be interpreted explicitly. The Comment column describes each type's internal representation. Informal Name Signed byte Unsigned byte Short Unsigned short Int Unsigned int Long Unsigned long Float or double Single Na ve int Unsigned na ve int Decimal Big number F# Type Keyword
sbyte byte int16 uint16 int uint32 int64 uint64 float or double float32 or single nativeint unativeint decimal bignum y uy s us (none) u L UL (optional) e f, (optional) e n un m I

Type Designation Symbol

Example Numeric Literals


3y 5uy 15s 100us 123 123u 9999999L 9999999UL 2., 1.01, 1.10e10 1.0f, 1.01f, 1.01e10 123n 123un 123m 123I

Comment 1 byte with a sign bit 1 byte with no sign bit 2 bytes with a sign bit 2 bytes with no sign bit 4 bytes with a sign bit 4 bytes with no sign bit 8 bytes with a sign bit 8 bytes with no sign bit 8 bytes with a sign bit 4 bytes with a sign bit Maps to System.IntPtr. Size is pla orm-specic. Maps to System.UIntPtr. Size is pla ormspecic. Maps to System.Decimal. Appropriate for nancial calcula ons. Maps to Microsoft.FSharp.Math.BigInt

Table 3.1: F# data type

When you suffix a numeric constant with one of the type designation symbols, as shown above, you're instructing the compiler to treat the literal as that exact type. For example, F# normally interprets the literal 100 to be a 32-bit integer. If we want to treat the value as a short (16-bit value), we would write 100s.

Of course, F# supports a variety of other data types, including Booleans, characters, strings, records, etc. We will explore each of these data types in subsequent chapters.

Expressing Numbers in Alternate Bases


F# supports expressing numbers in alternate bases including hexadecimal, octal and binary. Expressing a number in an alternative base does not change the type of the number - it simply changes its form.

Hex
To express a number in hex, prefix the value with 0x or 0X, e.g., 0x7F, 0XAA.

Octal
To express a number in octal, prefix the value with 0o, (a zero followed by a lowercase "o"), e.g., 0o123 (kind of weird).

Binary
To express a number in binary, prefix the value with 0b or 0B, e.g., 0b1001, 0B1100.

Variables vs. Value Binding


In many functional programming languages, including F#, we make a semantic distinction between variables and values. In imperative and OO languages, we normally think of variables as labels for computer memory areas that change over time. When the assignment statement "a = 3" is executed in most languages, the memory storage location called 'a' has its bits changed to the bits for the value 3. This is standard operating procedure in imperative and OO systems. In contrast to variables, F# prefers the terminology values or value bindings. In F#, when you execute "let a = 3", you have to think of the symbol, 'a', as being a pointer that is changed to point to the new value, '3'. Executing the statement changes the pointer, not the memory storage it points to. The old value that 'a' pointed to was not overwritten! (If it is not bound to any other symbol, the memory where it was stored will be garbage collected at some point.) We thus say 'a is bound to the value 3', not 'a is changed to the value 3'. The difference between variables and value binding is that a value is considered constant (readonly never overwritten), whereas a variable is expected to change (be overwritten). The concept of value binding supports one of the bedrock tenets of functional programming: no side effects. One way to achieve "no side effects" is to discourage (as in F#) or prevent (as in other functional languages like Haskell) a value from changing during assignment. You may be wondering how on earth you can write "real" software without side-effects. I ask that you suspend disbelief for a short amount of time and trust that it's possible, and that F# also provides mechanisms that enable "normal" variable-like behavior.

let There

be Values

Now that we understand the difference between variables and values[1], it makes sense to discuss how to define values and initialize them. This is the role of the keyword let, one of the most oft-used keywords in F#. With respect to values, the let keyword performs two jobs:
let let

binds a symbol to a data value introduces a new symbol scope.

Let's (no pun intended) take a look at an example:


let n = 123 \\ n is a value. let binds the symbol n to the integer 123.

If you wanted to test this using the F# Interactive Console, you would type
let n = 123;; \\Note the ;;[2]

Note that in neither of these examples did we specify the type of the value n. F# uses contextual clues and type inference to "figure out" that n is an integer. In this case, the type system had it pretty easy, since the data 123 is an integer. Once symbols are bound, their values cannot change. The only way to "change" the value of a bound symbol is to assign it a brand new value. The following code assigns the symbol x to one value, then subsequently reassigns it to a new value. The old value is abandoned, as is the original symbol's type.
let x = 123;; let x = 456.0;; let x = x + 1.0;; \\x is bound to 123, it's type is integer. \\x is bound to 456.0, it's type is float \\x is bound to 457.0, it's type is float

In the last line, the x that is declared on the left hand side of the = sign is considered to be a new symbol. It has the same name as a previously defined symbol and thus supersedes it. The old memory location referenced by the original x (456.0) still exists, but it is no longer controlled through x. This memory is essentially abandoned and will be reclaimed by the garbage collector.
let

supports a convenient syntax for assigning to multiple identifiers on a single line:


\\a=100, b=200 \\x=5, y=4, z=3

let a, b = 100, 200 let x, y, z = 5, 4, 3

Unit
While we are discussing types, it makes sense here to introduce the data type unit (http://msdn.microsoft.com/enus/library/dd483472(VS.100).aspx) . unit is a built-in type that only ever has one value, written like this: (). For example:
let x = ()

F#'s unit type is akin to void in other languages it is the "no value" indicator; however, since all F# constructs are ultimately expressions, we need a way to represent "expressions that have no real type to evaluate to" or alternatively, "expressions that evaluate to void." Since void is not a valid value type, F# needs another mechanism to indicate "an expression whose ultimate value is of no interest" this is the role of unit. From the MSDN documentation on unit:

The value of the unit type is often used in F# programming to hold the place where a value is required by the language syntax, but when no value is needed or desired. An example might be the return value of a printf function. Because the important actions of the printf operation occur in the function, the function does not have to return an actual value. Therefore, the return value is of type unit.
We will see unit used in a variety of contexts throughout the text.

void
Note that F# also supports the keyword void. It is used when interoperating with other .NET languages such as C#. It plays no role in F# otherwise, and is not the same as unit.

Understanding F#'s Feedback


Remember that F# only deals in expressions. This means that every complete programming construct has a data type and a value associated with it (after execution). When you enter the following expression in the F# Interactive Console
123 + 456;;

you will see the following output (Figure 3.1):

Figure 3.1

Here you can see that F# returned val it: int = 579. This means that the expression 123 + 456 returned a value considered to be an integer. Here are several other examples using numeric types along with their type designation symbols (Figure 3.2).

Figure 3.2

Different F# expressions yield different result types. We will discuss many examples of this in subsequent chapters.

Numeric Type Conversions


Despite F#'s sophisticated type inference system, there are times when we want to explicitly state a value's type. This is necessary, for example, when mixing different numeric types in the same expression, as F# does not automatically cast numbers for upward compatibility. To explicitly state a value's type, you can use type designator symbols, as previously shown, or you can use F#'s conversion operators. The name of each conversion operator is the name of the target type. For example, to convert an integer to a float32:
> let a = float32 100;; val a : float32 = 100.0f \\Convert the int 100 to a float32 value \\F#'s feedback. a is a float32 with value 100.0

The use of parentheses is optional, e.g., let a = float32(100);; yields exactly the same results as above. Each of the F# numeric types has an associated conversion operator. Some additional examples follow:
let a = float 100.0 let b = nativeint 1.23 let c = double 0xFF

Explicit Typing
In addition to using type designators and conversion operators, F# support explicit value typing. To explicitly define a value's type, you can suffix the value name with a colon and a type name. The following example defines two values, x and y. x is assigned the value 100.0 and, by the absence of an explicit instruction, we allow F#'s type system determine its data type. We make the same assignment with y; however, in y's case, we explicitly specify its type as double:
let x = 100.0 let y:double = 100.0;;

When we execute this code in the F# Interactive Console, F# responds accordingly:


val x:float = 100.0 val y:double = 100.0

As you can see, as in the case of x, F# would normally assume 100.0 to be float. By explicitly stating our type preference using :double, we bypass F#'s type inference system and force the data typing ourselves. We will use this form of explicit typing somewhat frequently when passing values to functions.

Immutability
By default, all values are immutable. This means that the memory associated with an identifier, once assigned, is fixed and cannot be changed subsequently through that identifier. For those coming from a mainstream programming background, this sounds ludicrous, and the two questions that immediately comes to mind are, "How can you build programs without variables?" and "Aren't variables the cornerstone or programming?" In the realm of pure functional programming, the answer is "no." In pure functional programming, you "change" a value by producing a new copy of the value with a modified state. For example, let's say you were working with a user-defined data type called Employee that had a name and a salary component. If you wanted to "change" the Employee's salary, you would create a new Employee with the same name as the original and a new value reflecting the updated salary. F# is not a pure functional programming language; therefore, while it discourages mutability in line with its functional heritage, it does not prevent it. F# enables value mutability via the mutable keyword. F# provides this functionality both to support multiparadigm development, as well as enabling frictionless integration with imperative and OO languages such as C#. To specify that a type is alterable, we decorate the name of the identifier with the keyword mutable:
let mutable x = 123

Once you've defined a value as being mutable, you can update its value using the destructive assignment operator (<-). For example:
x <- 456

This ensures that the memory referenced by x is changed accordingly. No new value is created. The memory referenced by x is still controlled by x. Note that we did not use the = operator here. If we were to write let x = 456 vs. x <- 456, we would have shadowed the old x variable, obviating the fact that x is mutable in the first place. Mutable values and destructive assignment go hand in hand. In general, when programming functionally, we try to avoid using mutable values and thus avoid side effects. As a rule of thumb, we do this by creating new values vs. changing what we already have. This "no side effects" mantra helps us to write programs

that are multithread and multi-process friendly, since immutable state leads to thread agnosticism. That being said, in real-world programs, it's impossible not to introduce some side effects, e.g., reading a value from the keyboard or a file constitutes a change in state. In addition, at some point we need to take speed and throughput into consideration, and making lots and lots of copies is much slower than changing an existing entity. So we need to often balance functional purity[3] with practical reality.

Numeric Operations
F# supports the arithmetic and numeric operations that you've come to know and love in other languages. F# supports unary operators, e.g., negation, as well as binary operators, e.g., addition, etc. You can find the documentation of arithmetic operations here. (http://msdn.microsoft.com/en-us/library/dd469493(VS.100).aspx) Table 3.2 below summarizes the arithmetic operators and provides examples of their use.

Arithmetic Operator Examples


Example
let a = 100 + 200 let c = 123 * 456 let b = 456 - 123 let d = 100 / 3 let e = 100.0 / 3.0 let f = 100.0 / 3 let g = 10 % 4 let h = 5.0 ** 3.0 let i = 1 + 2 * 3 (answer is 7) let i = (1 + 2) * 3 (answer is 9)

Comment Addi on Mul plica on Subtrac on Division. Since both parameters are integers, answer (33) is integer. Division. Since both parameters are oat, answer (33.3) is oat. Error. Cannot mix oat and integer. Use 100.0 / 3.0 or conversion operator. Modulus Exponen a on (note the oats) Default evalua on order of mathema cal expression. Parentheses ( ) override default evalua on order of mathema cal expressions.
Table 3.2: F# math operation

Mathematical Operators
Through the Microsoft.FSharp.Core.Operators (http://research.microsoft.com/enus/um/cambridge/projects/fsharp/manual/fsharp.core/microsoft.fsharp.core.operators.html) library, F# includes a number of useful

mathematical operators. These include trigonometric functions such as cos, sin, tan, rounding functions such as floor and ceiling, etc. The operators in this library allow for overflow and underflow, and will throw exceptions in the face of such conditions. If you need mathematical operators that check for boundary conditions, see Microsoft.FSharp.Core.Operators.Checked.
(http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/fsharp.core/microsoft.fsharp.core.operators.checked.html)

Bitwise Operators
F# also supports bitwise operators. These operators enable your F# programs to manipulate data at the bit-and-byte level. You can find the documentation of bitwise operators here (http://msdn.microsoft.com/en-us/library/dd469495(VS.100).aspx) . Table 3.3 below summarizes the bitwise operators and provides an example of their use.

Bitwise Operator Examples


Example
let a = 1 &&& 2 let d = 0xF <<< 1 let b = 2 ||| 3 let e = 2 >>> 3 let c = 4 ^^^ 5 let f = ~~~5

Comment Bitwise AND Bitwise le -shi Bitwise OR Bitwise right-shi Bitwise XOR Bitwise nega on. Unary operator.
Table 3.3: F# bitwise operator

The bitwise operators can be used with the following data types: byte, sbyte, int16, uint16, int32 (int), uint32, int64, uint64,
nativeint, and unativeint.

Units of Measure
In addition to the traditional numeric data types and operators that you find in other languages, F# supports an interesting feature called units-of-measure . This is a mechanism by which you annotate floats and integers with statically-typed unit metadata, providing a way to ensure that your programs deal consistently with data such as weights, lengths, forces, etc. To tap into the units-of-measure functionality, you first define one or more units that you wish to use, e.g., meters or seconds, in your program. To define new units of measure, you use the type keyword annotated with the Measure attribute[4]. In the following example, we define a new unit of measure, called m, that represents meters. We also define and a unit of measure called s that represents seconds:

[<Measure>] type m [<Measure>] type s

\\meters \\seconds

We can now use these measures to classify or decorate numeric values, and subsequently use these decorated values in calculations. For example, assuming that we've defined m and s above, we could use them as in the following manner (F# Interactive Console interaction shown):
> let distance = 123.5<m> - let time = 5.0<s> - let speed = distance / time \\using meters \\using seconds \\mixing units

If we enter this code in the F# Interactive Console, F# provides the following feedback:
val distance : float<m> = 123.5 val time : float<s> = 5.0 val speed : float<m/s> = 24.7

F# seems to understand that the result, speed, is of type <m/s>, a unit it derived from the inputs. Take note, however, that F# does not understand the semantics of the units - it simply uses basic mathematical mechanics to ensure that the units are combined to be arithmetically consistent. Measures are akin to data types in that they help qualify and constrain how a value is used. The compiler uses measure information to ensure that you don't use a float<s> where you mean to use a float<m>. For example, given the previously defined units m and s, we can see that mixing them in a single expression can cause problems:
let let let let let let a b c d e f = = = = = = 100<m> 200<m> 5<s> a + b a + c c * c

\\OK, d = 300<m> \\ERROR, The unit of measure do not match \\OK, f = 25<s^2>

Units of measure help to ensure the semantic consistency of calculations, e.g., you are using all metric units vs. English units, or US dollars vs. Euros. In the following example, we are using two measures - one for US dollars and one for Euros. Because we've decorated our values with measures, F# prevents us from making mistakes in our calculations:
[<Measure>] type usd [<Measure>] type eu let salary = 100000<usd> let raise = salary + 10000 let raise = salary + 10000<usd> let raise = salary + 10000<eu> \\US dollar \\Euro \\ERROR, int units do not match int<usd> units \\OK, units match \\ERROR, units do not match

We can also define new units of measure based on previously defined units of measure. For example:
[<Measure>] type kg [<Measure>] type N = (kg * m)/(s^2) [<Measure>] type Pa = N/(m^2) \\kilograms \\Newtons \\Pascals

The F# units-of-measure system also supports conversion constants (and functions, but we will leave that discussion for when we discuss functions in detail). These enable us to define conversions and conversion ratios between different measurement systems. The following example defines a conversion constant describing the relationship between centimeters and inches:
[<Measure>] type cm \\centimeters [<Measure>] type inch \\inches let cmPerInch = 2.54<cm/inch> \\conversion constant

Once defined, you can use conversion constants quite naturally. For example, given the definition of cm, inch and cmPerInch above, we can use them in calculations:
let myHeightInches = 72.0<inch> let myHeightCm = myHeightInches * cmPerInch

Note that I used 72.0 (a float) vs. simply 72 (an int) as myHeightInches. This is because I want to use myHeightInches in a calculation involving cmPerInch. Since cmPerInch is a float, I must ensure that all of the numbers used in calculations alongside cmPerInch are floats as well. Otherwise, F# will report (rather opaque and confusing) type-related errors. For example, if we change the lines above to:
let myHeightInches = 72.0<inch> let myHeightCm = myHeightInches * cmPerInch \\Note the absence of .0

We get the following error:

error FS0001: The type 'float<cm/inch>' does not match the type 'int<'u>'

This 'u is not a typo. It's how F# indicates generic types. We'll discuss generics in a subsequent chapter. Note that units of measure are compile-time constructs only. They help the compiler to enforce the semantic integrity of calculations, but they play no role at run-time, like real types do.

F# Power Pack
The F# PowerPack (FSharp.PowerPack.dll) (http://www.microsoft.com/DOWNLOADS/details.aspx?FamilyID=e475a670-9596-4958-bfa2dc0ac29b4631&displaylang=en) is a library from Microsoft that contains additional components and tools for building F# applications. I mention the F# Power Pack here because it ships with units of measure, e.g., physical constants, that you may find useful when building your F# applications. I will refrain from using the F# Power Pack and other add-on libraries in this book, so as not to confuse you regarding what is core vs. what is from additional libraries.

Printing (Outputting) Values


To display values in an F# program, or to format them in the F# Interactive Console, you can use the printf and printfn[5] functions. These functions accept 0 or more format specifiers and a corresponding number of parameters, and format the result as a string. For example:
let city = ""Boston" let temp = ""63.5" printf ""The mean temperature for %s is %f" city temp

Executing this code, we get:


The mean temperature for Boston is 63.500000

Note that the parameters are not separated by commas. They are separated only by white space. The format specifiers that you can use in for printf and printfn are the same ones found in the .NET String.Format (http://msdn.microsoft.com/en-us/library/fht0f5be.aspx) method. Remember that you can also use the functions from the F# Printf module (http://msdn.microsoft.com/en-us/library/ee340484(VS.100).aspx) .

What You Need to Know


F# supports all kinds of literal numeric constants, numeric types, and numeric operations on values. F# prefers the concept of "value binding" to "variable assignment." We will sometimes slip and use the imperative term. In this text. We think you will understand what we mean. You bind a symbol to a value using the keyword let and the equals sign, e.g., let x = 3. F# uses the special type unit to designate "no value." F# supports the keyword void for compatibility with other .NET languages, but that is not the same as unit. You can explicitly control a numeric literal's value type by using type designators, e.g., let x = 3.0f. This also implicitly determines the type of the symbol, x. In F#, values are immutable by default. You can use the keyword mutable to make a value changeable. The destructive assignment operator <- is used to change the value of a previously bound identifier, e.g., x <- 5. F# supports all the arithmetic operations and bitwise operations on numeric values that you are familiar with from other languages. F# supports using parentheses to force the order of mathematical evaluation. F# supports units of measure, which you won't find in most other languages. Units of measure enable you to annotate integer and floating point values with units, e.g., distances, weights, temperatures, etc. You can work with unit-rich values, and the compiler will help ensure that you don't accidentally mix unit types, e.g., dollars and Euros. Units of measure are compile-time constructs. Units of measure have no impact at runtime. They are just for compile time checking.
[1]

I may inadvertently use the term variable in some parts of the text. This comes from 20 plus years of developing software. Please consider the term synonymous with symbol when I use it. [2] I will use both forms of example throughout the text. Keep in mind that expressions ending in ;; are from the F# Interactive Console. [3] Even pure functional languages, e.g., Haskell, allow for side effects, although they do so differently than allowing values to be destructively assigned. We'll discuss exactly how they realize state changes in a later chapter. [4] We are using the standard .NET attribute model here. The only thing that is "F#-ish" about it is the angle bracket syntax. We will fully cover F#'s definition and use of attributes in a subsequent chapter [5] printf and printfn are the same except for that printfn forces a newline at the end of its output stream.

Chapter 4 Chars & Strings


Introduction
In addition to the numeric types we covered in Chapter 3, F# supports character and string data. In this chapter, we'll look at the different ways in which we can express characters and strings, and the different operations we can perform with them.

Character Data
In F#, characters are of type char, and are manifestations of the System.Char (http://msdn.microsoft.com/enus/library/system.char(VS.71).aspx) type in .NET. We define characters by delimiting symbols in single quotes. Characters are internally represented in Unicode. In the following example, the identifier c is bound to the character x.
let c = 'x'

You can also represent a character literal as a byte by adding a B suffix to the character.
> let c = 'x'B;; val c : byte = 120uy

Because they are System.Chars, F# characters offer a number of useful methods, most of which are defined as static members of the System.Char class, e.g., Char.IsDigit. While System.Char instances have a few interesting methods in their own right, most of a Char's usefulness comes from its class methods.

Representing Characters by Code


The character symbols that a computer is capable of displaying all come from a well-known, fixed pool of symbols. These symbols are divided into sets called code pages or character encodings. A code page is basically a finite, fixed set of numbered symbols. Every character is represented by a number corresponding to it entry in the code page. For example, in the ASCII code page, the capital letter 'A' corresponds to entry 65. This means that my program can display the capital letter 'A' by accessing entry 65 from the ASCII code page. Note that all operating systems and applications use a default code page. There are several ways to express a character as an entry from a code page (a number). The following list highlights the various alternatives:
\NNN is a 3-digit integer for representing a character. For example '\065' = 'A' \uNNNN (Unicode) is a u followed by a hex representation of the number corresponding to the example, '\u0041' = 'A' \UNNNNNNNN (long Unicode) is a U followed by a 2-byte hex sequence representing the number character. For example, '\u00000041' = 'A'

given character. For corresponding to the given

Strings
Life wouldn't be all that interesting if all we had to work with were single characters. F# fully supports strings (http://msdn.microsoft.com/en-us/library/dd323829(VS.100).aspx) , which map to the System.String (http://msdn.microsoft.com/enus/library/system.string(VS.71).aspx) type. Strings are an ordered collection of Unicode characters. F# strings are immutable and are delimited by double quotes. Here are examples:
let daughter = "Melissa" let pet = "Sugar"

Strings can be single- or multi-line. To enter multi-line strings, simply enter a newline at the end of each line of the string:
let haiku = "No sky no earth - but still snowflakes fall"

If you want to enter a single, long string on multiple lines, use the backslash character to continue the string on the next line. This will prevent a newline from being inserted.
let haiku = "No sky\ no earth - but still\ snowflakes fall"

The above example will yield a string with no newlines embedded.

Strings are stored in memory as an ordered collection of characters. This ordered collection is an array. [1] This means that we can access the individual elements (characters) of an array by referring to its position in the array. Positions start at 0. For example:
let daughter = "kimberly" let first = daughter.[0] let last = daughter.[7] \\string \\first character, 'k' \\last character, 'y'

Strings are Buckets of Characters

For those coming from other languages, note the . after the identifier name and before the braces. You need to use this syntax in F# to access array elements. You can also convert a string to a corresponding array of bytes via the B suffix. For example:
> let countryBytes = "USA"B val countryBytes : byte array = [|85uy; 83uy; 65uy|][2]

When you suffix a string with a B, F# interprets the characters as ASCII bytes. (Darn, there's that code page thing again).

Escape Sequences
The familiar escape sequences work like they do in other languages such as C and C#, e.g., \n is a line return, \t is a TAB, etc.

Verbatim Strings
All too often in programming, we deal with strings that contain file paths and names that, by necessity, include backslashes and other special symbols that we need to escape. Here is where verbatim strings come to the rescue. Verbatim strings are not interpreted they are processed as-is. The following example demonstrates using a verbatim string to represent a file path:
let mydir = @"c:\dev\fsharp\examples"

The at (@) symbol initiates a verbatim string, allowing for the single backslash (\) to appear without issue.

String Operations
Strings in F#, since they map to System.String, enjoy all the functionality the .NET libraries have to offer. Some operations available to our programs are illustrated below.
let let let let fullname = "Mary " + "Smith" s = "hello " + string 100 len = fullname.Lenght i = fullname.StartsWith("Mary") \\concatenation \\concatenation, string conversion operator \\10 \\true

Like the numeric conversion operators we discussed in Chapter 3, you can use the string conversion operator to cast a numeric value to a string representation, as in the example above. Since strings are immutable, you cannot execute any operation that would change them, even via accessing their individual components. Given the example above, the line fullname.[0] <- "L" would cause a compiler error.

Building Long Strings


While you can build a string by concatenating onto its end, this is inefficient for all but the most trivial cases. Every time you append to the end of a string, immutability dictates that F# creates a new string with the combined values. This is a very inefficient way to build a string. To build a string efficiently, you need to tap into the System.Text.StringBuilder (http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx) class. We will discuss interoperating with the .NET class libraries in a future chapter; however, in order to give you a sneak preview, here is an example of creating a .NET StringBuilder object and using its methods to build a string efficiently.
let buf = new System.Text.StringBuilder() buf.Append("Mary had ") buf.Append("a little lamb, it's ") buf.Append("(you know the rest)")

To retreive the built-up string, you can use the ToString() method:
let str = buff.ToString() printf "%s" str

What You Need to Know


F# supports characters, which are single Unicode elements delimited by single quotes. F# characters map to the System.Char type, e.g., let c = "x". Most of the interesting things you can do with characters come from the Char class, e.g., System.Char.IsDigit("x"). F# support strings, which are ordered collections of Unicode characters delimited by double-quotes.

F# strings map to the .NET System.String type and have access to all of its members and operations. F# strings are immutable. F# strings support standard escape sequences, e.g., \n. F# supports verbatim strings, e.g., let dir = @"c:\temp" You can access the individual elements of a string via array syntax, e.g., s.[0]. You can concatenate strings via +; however, for efficiency's sake, you should avoid doing so for all but simple cases. To build up long strings efficiently, avoid + and use the .NET System.Text.StringBuilder class instead.
[1] [2]

We cover arrays and other collection types in subsequent chapters. We will cover arrays in a subsequent chapter.

Chapter 5 Booleans & Conditionals


Introduction
Decisions, decisions! To make logical decisions, programming languages need a way to determine the truthfulness of a statement. In other words, they need to be able to determine whether an expression is true or if it is false. This chapter deals with Booleans, the stuff of true and false, and the ways in which your F# programs can employ them to conditionally alter program flow.

Booleans
The F# type bool maps to the .NET System.Boolean (http://msdn.microsoft.com/en-us/library/system.boolean.aspx) data type. It can hold one of two values: true or false.
let t = true let f = false

Boolean Operators
Boolean logic (http://computer.howstuffworks.com/boolean.htm) enables us to logically combine true and false values to perform calculations and make decisions based on the outcome. The Boolean operators are AND, OR and NOT. Each of these operators is represented in F# as a symbolic operator as shown in Table 5.1 below. Boolean Operator AND OR NOT && || not
Table 5.1: F# symbolic operator

F# Operator

The following code snippets demonstrate Boolean values used with logical operators.
let let let let let t = f = x = x = fls true false t && f t || f = not true \\true \\false \\false \\true \\true

In addition to the logical operators AND, OR and NOT, F# supports logical comparison operators (http://msdn.microsoft.com/enus/library/dd469493(VS.100).aspx) . Your programs can compare for equality, values being less-than, greater-than, etc. other values, etc. Table 5.2 below summarizes the available logical comparison operators.

Logical Comparison Operators


Operator
=

Notes Equality. This is not an assignment operator. It is used only for comparison. Note that F# does not use == for comparison, as many languages do. Greater than Less than Greater than or equals Less than or equals Not equal

Examples
2 = 2 1 = 2 \\true \\false

>
<

1 > 2

\\false

1 < 2

\\true

>=

1 >= 2

\\true

<=

1 <= 2

\\true

<>

1 <> 2 2 <> 2

\\true \\false

Table 5.2: F# comparison operator

Making Decisions

Once you can determine whether an expression is true or false, you can start using Boolean values to make decisions and alter program flow based on these decisions. The following section discusses the various ways that you can use Booleans to make decisions and conditionally execute code.

ifthenelse
The ifthenelse expression evaluates the truthfulness of a given Boolean expression and executes different branches of code depending on the result. The general form of the ifthenelse expression is as follows: Note that in F#, the ifthenelse construct is an expression.[1] This means that the ifthenelse construct evaluates to a value, which is the value of the last expression. If there is no explicit else branch, the construct evaluates to type unit. Therefore, in the absence of an explicit else clause, the then clause must evaluate to unit. Let's look at the consequences of this.
let a, b = 100, 200 if a < b then "a < b" if Boolean-expression then expression1 [ else expression2 ]

\\ERROR evaluates to string and not unit!

Here, we are telling F# that the expression evaluates to a string; however, this will generate an error. Why? Since there is no explicit else clause, the overall type of the if expression is unit. We are, therefore, trying to return a string where F# expects a
unit.

We can solve this problem by specifying an else clause that evaluates to the same type that we want to return from the other parts of the if construction. The following code shows the previous example sans the error:
let a, b = 100, 200 if a < b then "a < b" else "a is not less then b"

\\ERROR evaluates to string and not unit!

Now, because we have an explicit else branch that returns a string, the overall expression is expected to return a string. Given that all paths evaluate to a string, F# allows the construct with a warning. The warning in Visual Studio is: This expression should have type 'unit' but has type string. This warning message is telling us that the result of the expression isn't being stored anywhere the result is going to unit or "into the void". To correct this, we assign the expression to an identifier:
let a, b = 100, 200 let s = if a < b then "a < b" else "a is not less then b"

\\OK

Another way to correct this, or to "shut F# up" would be to tell it that we know we are explicitly ignoring the output, like this:
let a, b = 100, 200 (if a < b then "a < b" else "a is not less then b") |> ignore[2]

Another consequence of the if construct being an expression is that all branches must return the same data type. For example:
let a, b = 100, 200 let s = if a < b then 1 else "a is not less then b"

\\ERROR: This expression has type string but is used here with type int

Since the else branch evaluates to a string, the overall if construct must evaluate to a string. This means that all branches must evaluate to string as well. In the example above, we are evaluating the expression to an int where F# expects a string. One more example rounds out the possibilities:
let a, b = 100, 200 if a < b then printfn "a < b" \\OK. Since we have not denited an else branch, F# expects this \\if it evaluate to unit. printf evaluates to unit, satisfing \\this expectation.

Parenthesis
You can use parenthesis to clarify or group Boolean expressions, and to force evaluation order. The following example illustrates the idea:
let a, b, c = 100, 200, 300 if ((a < b) || (c < b)) && (a < c) then printfn "a is the lowest value"

Parentheses are optional when using them for clarity. They are mandatory for forcing evaluation order.

Multiple Branches
The ifthenelse construct can evaluate multiple expressions using the else if or the elif construct. elif is a convenience keyword and is exactly the same as spelling out else if. Let's look at a few examples:
let name, pin = "bob", 123 let securityMessage = if name = "bob" && pin = 123 then "welcome bob!" elif name = "sally" && pin = 456 then "welcome sally!"

else "access denied"

In this example, securityMessage gets bound to the value welcome bob!. Remember that in F# whitespace is significant. F# uses whitespace to logically and semantically group multiple lines of code together. Failure to indent or misalign the ifelifelsethen above causes compiler errors. The following example shows how F# uses indentation to group multiple statements.
let name = "bob" let s = if name = "bob" then printfn "bob is a palindrome" "bob backward is still bob" else printfn "access denied" "who are you?"

This example prints bob is a palindrome"and evaluates to the string bob backwards is still bob"The final expression of each block is what the entire block evaluates to. You may be thinking to yourself that F#'s decision-making capabilities are rather rudimentary. You may be asking, "Where's my switch statement?" Well, it turns out that F# does not support a switch statement. Instead, it supports something much more flexible and powerful called pattern matching expressions. To take advantage of pattern matching expressions, we need a little more F# under our belts, so we'll wait to explore them in Chapter 11.

What You Need to Know


A Boolean (F# bool) is a true or false value. F# supports the Boolean operators AND (&&), OR (||), and NOT (not). You can test values for equality and inequality using comparison operators, e.g., =, <=, <>, etc. You can use parenthesis to group and/or clearly delineate Boolean expressions. The ifthenelse construct evaluate to an expression. If you do not specify an explicit else clause, the entire construct is assumed to return unit. If you do specify an else clause, the construct is assumed to evaluate to the else's return type. When chaining multiple if expressions together, you can use elif as a convenience for else if. Whitespace is significant and is used to group multiple expressions together under a given if or else clause.
This is different from other .NET languages like C#, where if is a statement. I know we have not yet covered this construct. It simply pipes the result of the expression to the special function ignore, which accepts anything and simply does nothing with it. We will discuss the pipe symbol |> and the ignore keyword in subsequent chapters.
[1] [2]

Chapter 6 Imperative Loops


Introduction
Because F# supports multi-paradigm development, it supports standard (read imperative) looping constructs. In general, functional programming favors recursion to imperative looping, in part because it favors zero side effects. For now, we'll stick to imperative looping structures, and we'll move into recursive loops in subsequent chapters.

Imperative Looping Constructs


F# supports two types of imperative loops that are familiar in style and content to loops in imperative and OO languages like C# and Java.
fordo whiledo

fordo Loops
fordo

loops enable you to iterate over a range of values. A fordo loop takes the following general form:

for identifier = start [to | downto] finish do body-expression

Let's look at some examples:


\\Output the numbers from 1-10. Note you do not \\need to declare the loop variable with let. for i = 1 to 10 do printfn "i = %d" i \\Count from 1 to 10, with identifiers let a, b = 1, 10 for k = a to b do printfn "k = %d" k \\Count down from 10 (down) to 1 for j = 10 downto 1 do printfn "j = %d" j \\Sum the first 5 non-zero integers. \\This is quite "imperative". We'll see its functional cousin later. let mutable sum = 0 for n = 1 to 5 do sum <- sum + n printfn "current sum = %d" sum

F# for loops are technically expressions. They evaluate to unit. There is another form of the for loop, called forin, that is used to iterate over collections. We will cover this form of the for loop in the chapter covering collections.

whiledo Loops
The whiledo loop is an expression used to perform iterative execution so long as a given Boolean condition evaluates to true. The whiledo loop takes the following general form:
while test-expression do body-expression

In whiledo loops, the test expression is evaluated and must resolve to true or false. If the expression evaluates to true, F# executes the body of the loop at least once. After executing the body of the loop, F# reevaluates the test expression. If the test expression evaluates to true, the body is executed again. This process repeats until the test expression evaluates to false. The test expression can be composed of multiple Boolean conjunctions, and can use parentheses and logical operators to group subexpressions and to force evaluation order. Follow are a few examples of the whiledo loop in action:
\\Output numbers from 1-10 and squares let mutable n = 1 while n <= 10 do let sq = n * n printfn "%d %d" n sq n < n + 1

\\Note mutable applies to both identifiers below let mutable a, b = 1, 10 while b >= a do printfn "%d %d" a b a < a + 1 b < b - 1 \\Using parentheses and Boolean conjuntion let mutable a, b, c = 1, 10, 0 while ((a > b) && (c < 3)) do printfn "%d %d %d" a b c c < c + 2 \\WARNING: Infinite loop ahead! while (true) do printfn "F# is great!"

If you're running F# code in the F# Interactive Console, and you've accidentally coded an infinite loop, you can abort the loop via pressing Ctrl-. (Control-period).
\\WARNING: Body never executes while (false) do printfn "This will never be output!"

Unlike other programming languages, F# does not currently support unconditional loop termination statements such as C#'s break and continue statements. However, we should point out that the F# reference documentation says that the keywords ' break' and 'continue' are reserved for future use.

What You Need to Know


As a multi-paradigm language, F# supports imperative looping constructs in the form of fordo and whiledo loops. fordo loops are generally used to iterate a fixed number of times, e.g., from 1 10 or from 100 down to 0 whiledo loops are generally used to iterate as long as a given expression evaluates to true. Unlike other languages, F# imperative loops do not currently support unconditional jumps, e.g., like C#'s break and continue statements. Although it supports imperative looping, F# tends to favor recursive looping due to the fact that recursion limits side effects. We will see examples of recursive looping in subsequent chapters.

Chapter 7 Tuples & Arrays


Introduction
F# supports a large number of interesting built-in data types. We continue our exploration of F#'s built-in types by looking at the tuple (rhymes with "supple" or "too-pull" depending on who you are) and the array. You use these types as simple containers for multiple values.

Tuples
Tuples are defined by the .NET type Microsoft.FSharp.Core.Tuple.[1] Tuples are simple containers or groupings of ordered, unnamed values of possibly different data types. A tuple can contain two or more values and/or expressions. The following examples illustrate a few tuples and one integer:
(1, 2.0) (1, "two", 3.0f) (42) \\tuple of two values, different data types: int and float \\three values, different data types \\NOT a tuple just an int surrounded by parentheses

Tuples can contain values, expressions, or a mixture of both. In the following example, we see a tuple containing a string and an expression that evaluates to an integer:
("mary", 1 + 2 + 3) \\simple expression

Tuples can also contain other tuples:


(1, (2, 3)) \\tuple containing another tuple

As we saw in the previous chapter, looping constructs are expressions; therefore, since tuples can store expressions, we can store bits of code in them. Here is an example:
("joe", for x = 1 to 10 do printfn "%d" \\more complex expression, fordo

fst and snd


F# defines two convenience functions for working with tuples: fst and snd. fst returns the first element of the tuple, while snd returns the second element. There is no general access function for retreiving the nth element of a tuple, even though they are allowed to contain more than two elements.[2] Let see how to use fst and snd:
let t = ("joe", 65000.0) let guy = fst t let salary = snd t \\t is the tuple \\guy = "joe" \\salary = 65000.0

Understanding F#'s Feedback


Like all other values in F#, tuples are bound to a fixed, static data type. Tuple data types are expressed by writing their component types, in the order they appear in the tuple, separated by asterisks. The following illustrates the general form of a tuple type (alliteration is fun):
type1 * type2 * * typeN

Let's use the F# Interactive Console to investigate how F# looks at tuple data types:
let t = (5, 25) \\val t: int * int = (5, 25)

In this example, we see that t is a tuple that contains two integers (int * int). The symbol * in this case is not multiplication, but the symbolic mechanism by which F# defines a tuple. Let's look at another example:
let v = ("boston", 42.35, -71.06) \\val v : string * float * float = ("boston", 42.35, -71.06)

Here we see a 3-member tuple of type string * float * float. This tells us that the tuple is expected to contain a string, followed by a float, followed by another float. With this knowledge, we can define tuple types explicitly. The following example defines a tuple data type that includes an integer-float-boolean triplet:

let t: int * float * bool = (100, 123.4, true)

While contrived and unnecessary in this instance, this example demonstrates how to properly define a tuple type (int * float * bool). We will see uses for this when we discuss defining discriminated unions later in the book.

Use of Tuples
Tuples are most often used in the following ways: as simple data "containers" to group multiple, related items to pass in multiple arguments to a function (yet to be discussed) to return multiple values from a function (yet to be discussed)

Arrays
F# arrays are defined by the .NET data type Microsoft.FSharp.Collections.Array sequences of consecutive data elements, all of the same type.
[3]

(http://research.microsoft.com/en-

us/um/cambridge/projects/fsharp/manual/fsharp.core/Microsoft.FSharp.Collections.Array.html) . Arrays are fixed-sized, zero-based, mutable

Creating and Accessing Arrays


You can create arrays in one of several ways. The general form of a simple array creation is as follows;
let arr = [| element1; element2; | or array comprehension |]

To create small arrays, you can list out the individual elements, as in the following example:
let evens = [| 2; 4; 6; 8 |]

Note that F# uses semi-colons (;) to separate elements in arrays (and lists, etc., as we'll see later). You can also put each element on a separate source line, in which case the semicolon separator is optional. For example:
let cities = [| "Boston" "Chicago" "Phoenix" "San Francisco" |]

To access the elements of an array, we use a zero-based index. Continuing with the previous example:
printfn printfn printfn printfn "%s" "%s" "%s" "%s" cities.[0] cities.[1] cities.[2] cities.[3] \\Boston \\Chicago \\Phoenix \\San Francisco

Note that you must use the . before the brackets [] in order to access the given element. This may look strange to those coming from C-like languages. To create arrays without needing to explicitly specify array elements individually, we can use array comprehensions or Array.zeroCreate. Let's look at each of these options now.

Simple Array Comprehensions (Ranges)


A simple array comprehension uses ranges to create array elements. The general form of an array comprehension that uses ranges is illustrated below:
let arr = [| start_value..step..end_value|]

The step, which is optional, is the value added to the start_value and successively generated values in other words, it's the "count by" parameter. In the following examples, we use different ranges to fill our arrays:
let nums = [|1..10|] let nums = [|2..2..100|] let nums = [|5..2..25|] \\1-10 inclusive \\All even number from 2-100 inclusive \\All odd number from 5-25 inclusive

We can use ranges to count backwards as well, by having the step be negative:
let nums = [|10..-1..1|] \\10, 9, , 1 inclusive

Array.zeroCreate
Array.zeroCreate is a method of F#'s Array class that enables us to allocate an array of a given size. Each element of the array initially contains a null (for non-numeric types) or 0 (for numeric types) value. The following example allocates an array of 10

integers that stores the first 10 multiples of 5:


let nums = Array.zeroCreate 10 for i = 0 to 9 do nums.[i] <- 5 * (i + 1)

Note that if you just typed in the first line of the above example in the F# Interactive Console, you would get an error message, because F# does not have enough information to determine what type elements are in the array. On the other hand, if you enter all three lines before adding the final ;;, there is no error, because F# does have enough information to deduce that the array contains elements of type int.
Array.zeroCreate

is one of many methods defined on F#'s Array class. It takes a parameter that indicates the size of the array to create. The returned array can contain any homogenous type. For example:
let names = Array.zeroCreate 5 for j = 0 to 4 do names.[j] <- "Name" + string j

Note the use of the destructive assignment operator (<-) above. When dealing with arrays, you cannot use let to bind a value to an array element you must use the <- operator. The following code yields a compiler error:
let nums = Array.zeroCreate 10 let nums.[0] = 100 \\^^^- Unexpected symbol '[' in binding

If you attempt to use what you might traditionally think of as the assignment operator, the code compiles fine; however, the result is not what you'd expect:
let nums = Array.zeroCreate 1 nums.[0] = 123 \\result: val nums : int array = [|0|] - what happened?!

This "assignment" does not take place because it is not an assignment. In F#, outside the context of let, the = symbol is used to test for equality it is not an assignment operator. Therefore, nums.[0] = 123 is actually a Boolean operation that compares the contents of nums.[0] (which is 0) to the value 123. The entire expression thus evaluates to false. And, if you use the proper <- operator for mutable assignment, nums is modified as you would expect, but note that the value of the entire expression is the full array nums, not just nums.[0].
let nums = Array.zeroCreate 10 nums.[0] <- 100; \\returns val nums : int[] = [|100; 0; 0; 0; 0; 0; 0; 0; 0; 0|]

Array Typing
A given array must contain elements of the same type. F# can generally figure out the type of elements an array contains based on context, as illustrated in the following example:
let nums = Array.zeroCreate 2 nums.[0] <- 123

Here, F# determines that the elements of the array are to be integers. Attempting to add another data type fails:
nums.[1] <- "hello" \\error FS0001: This expression has type string but is here used with type int

F# determines the type of the array from the first assignment (<-) it finds lexically. For example:
let elements = Array.zeroCreate 2 elements.[1] <- "hello" elements.[0] <- 123 \\error FS0001: This expression has type int but is here used with type string

The fact that we are assigning to elements.[1] vs. elements.[0] makes no difference to the typing system. Since F# found the first assignment to be a string, it expects all array elements to follow suit, regardless of their index.

Explicitly Defining an Array's Type


As with simple numeric types, we can explicitly specify an array's type. To create an array that contains 3 strings, for example, we could use any one of the following lines of code.
let kids1: string[] = Array.zeroCreate 3 let kids2: string array = Array.zeroCreate 3 let kids3: Array.zeroCreate<string> 3

Each of these lines results in the identifier kids being bound to a an array of 3 strings. Once we've defined these arrays, we can begin to assign values:
kids1.[0] <- "jessica" kids1.[1] <- "kimberly" kids1.[2] <- "melissa"

Slices
You can access a contiguous portion of any array, known as a slice, using slice notation. The general form of slice notation is:
array[start_index..end_index]

You can omit either the start_index or the end_index, but not both at the same time. Here are some examples of using slices:
let let let let let let nums = [| 'a'; 'b'; 'c'; 'd'; 'e'; 'f'; 'g'; 'h'; 'i'; 'j'; |] w = nums.[0..2] \\a, b, c x = nums.[5..8] \\f, g, h, i y = nums.[2..] \\c, d, e, f, g, h, i, j z = nums.[..5] \\a, b, c, d, e, f nums2 = nums.[0..] \\slice copy

With slice notation, the returned value is a new array that contains the specified elements.

Mutability
Arrays are implicitly mutable data structures. When creating an array, you do not need to explicitly use the keyword mutable. You can change any of the elements via the destructive assignment operator.
let nums = [| 1..10 |] nums.[0] <- 123

We have seen several examples of this already.

Multidimensional Arrays
A multi-dimensional array is literally an array of arrays. Multi-dimensional arrays come in several forms, generally referred to as rectangular and jagged arrays.

Rectangular Arrays
Rectangular arrays are arrays that contain one or more other arrays. These inner arrays all have the same length. The resulting data structure is like a grid or matrix. You can define a rectangular array explicitly, as in the following example:
let r = [| [| 1; 2; 3 |]; [| 4; 5; 6 |] |]

Here,r is a rectangular array composed of two single-dimension arrays, each with three elements. We can access each row individually, as shown in the following example:
r[0] = [| 1; 2; 3 |] r[1] = [| 4; 5; 6 |] \\the first row \\the second row

This array is of type System.Int32[][]. In order to work with this style of multidimensional array, you need to access individual rows, and from these, the columns. To access the number 4 for example, we need to access the second inner array (row 1), followed by the first column (column 0):
let r = [| [|1; 2; 3|]; [|4; 5; 6|] |] let row1 = r.[1] \\[|4; 5; 6 |] let num = row1.[0] \\4

You can access the same information using the more compact .[row].[col] syntax:
let num = r.[1].[0] \\4 note ueses of . operator two times

To make working with multidimensional arrays easier and more flexible, F# ships with several types from the Array family: [4] Array2D, Array3D and Array4D located in Microsoft.FSharp.Collections . Not surprisingly, you can create a 2D array using the Array2D type, as in the following example:
let matrix = Array2D.zeroCreate<int> 2 3

This creates a multidimensional array of 2 rows and 3 columns. The <int> tells F# that each element of the array must be an integer. This class provides convenient access to the array elements through the [row, column] operator vs. having to use the more awkward .[row].[col] syntax. For example, to set the second element of the first row to 123, we would write the following:

matrix.[0, 1] <- 123

You can also use Array2D to create an array where each element is initialized to a given value. For example, the following code creates a 2D array of 12 of integers (3 rows x 4 columns) and initializes each one to 100.
let percentages = Array2D.create<int> 3 4 100

If you explore Array2D in Visual Studio's Object Browser, you will see that it contains many methods, e.g., map. These functions are oriented towards the functional side of F#, which we begin to explore in ernest in the next chapter. It is interesting to note that 2D arrays created explicitly, e.g., nums = [| |] vs. those created via Array2D, e.g., nums = have a different underlying types. Let's see how F# views these different arrays:
let simple [| [|1..3|]; [|4..6|] |] let atype = Array2D.zeroCreate<int> 2 3;; > val simple : int array array = [| [|1; 2; 3|]; [|4; 5; 6|] |] val atype : int [,] = [[0; 0; 0] [0; 0; 0]]

Array2D.zeroCreate

Since these arrays are of different types, they will support different mechanisms for access, etc. For example, the simple array above does not support the convenient [row, col] access syntax (it does, however, support .[row].[col] access). This can get a little confusing. So, my advice: when working with rectangualr arrays, favor class-based arrays.

Jagged Arrays
F# support arrays of arrays where the "inner" arrays are of varying size, giving the entire array a "jagged" appearance when written out. Here is an example of an explicit jagged array:
let jagged = [| [|1; 2|]; [|3; 4; 5; 6|]; [|7; 8; 9|]; [|10; 11; 12; 13; 14|]; [|15|]; |]

The type of jagged is int array array. This is different from the explicitly defined rectangular array type shown in the previous example. To access the members of a jagged array, use the .[row].[col] syntax. For example, given the array jagged as defined above, we can access the number 12 by getting the contents of row 3, collumn 2:
let twelve = jagged.[3].[2]

Of course, if you supply an index value that is too large or too small (outside of the array bounds), F# throws an exception.

What You Need to Know


Tuples are ordered groups of unnamed, heterogeneous values. They are most often used to pass parameters into functions and to return multiple values from functions. .NET 4 introduces a new System.Tuple type usable from all .NET languages. Older versions of F# will use the Tuple defined in the F# core library. Tuple types are specified in the form type1 * type2 * * typeN. You can access a tuple's first element using the fst function, and the second using the snd function. Arrays come in several flavors including single-dimensional and multidimensional. Arrays are fixed-sized and contain homogenous data. Arrays are inherently mutable. To assign values to array elements, use <- as the assignment operator, not =. F# ships with classes called Array, Array2D, Array3D and Array4D. Favor these classes over defining arrays explicitly ( using [| |]) for all but the most trivial cases.
[1]

As of this writing, Microsoft.FSharp.Core.Tuple is not documented in the MSDN F# Language Reference. Note that .NET 4 introduces a System.Tuple type that F# may use as well. [2] We'll see how to retreive other elements of the tuple in a later chapter, when we discuss pattern matching. [3] This links to the documentation on the Microsoft Research site. At the time of this writing, Microsoft.FSharp.Collections.Array is not documented in the MSDN F# Language Reference. [4] As of this writing, these classes are not documented in MSDN. Use Visual Studio's Object Explorer to investigate them.

Chapter 8 Functions & Functional Concepts


Introduction
Up to this point in the book, we've learned about primitive data types, basic conditional structures, imperative looping constructs and simple collection types in the form of tuples and arrays. Arguably, most of what we've learned lives comfortably in the realm of imperative and OO programming. These are mostly familiar concepts encountered in other languages, and you should quickly be at ease using them on a regular basis in F#. This puts us in a good position to peel the onion and start exploring F#'s functional side. By studying functions and related functional programming concepts, we will be able to take advantage of F#'s more powerful and elegant data structures and mechanisms including lists, sequences, generic types, asynchronous processing, etc. To get started, we'll discuss what functions are, how they are defined and used, and how they interrelate to form powerful structures that are functional programming's raison d'tre.

Functions
As we saw in Chapter 1, mathematical functions are, in essence, transformations. They accept inputs and emit outputs. They produce no side effects, i.e., the inputs are unaffected by the function and the function does not affect global state. Functions are also predictable in that the same inputs will consistently and reliably produce the same outputs. Let's take the square root function, for example. The square root function takes as input a single parameter and returns a single return value. The input value and the output values are related solely by the given function, and the input value is unaffected by the execution of the function. The function will always return the same output for a given input. Before we delve into functional concepts, it makes sense to see how we define and work with functions in F#.

Defining Functions in F#
To define functions in F#, we use the let keyword, followed by the function name, an optional parameter list, the assignment operator =, and the body of the function. The general form of an F# function is as follows:
let funcname [parameter list] = function body

Every construct in F# is an expression; therefore, it evaluates to a value of a given type. The following examples demonstrate how to define functions in F#:
let let let let foo = 123 f x = x + 1 g(x)= x + 1 sumVals x y = x + y \\Function that takes 0 params and evaluates to a value \\Single parameter, return given parameter + 1 \\Optional parentheses. Exactly same as g x = x + 1 \\Apply operator + to values x and y

One interesting definition above is that of the function foo. "Wait a minute - isn't this just a value, like all the other values we've seen do far?" Yes, it is. What this tells us is that a value is just another type of function a function that takes no parameters and evaluates to a known quantity. This quantity may be a constant, or something computed. What this helps to show, I hope, is that as far as F# is concerned, there is no real difference between a value and a function. They are synonymous, and can be used very naturally together. We will explore this concept throughout the text.

Function Parameters
Let's now take a look at the next function, f. This function is more traditional in that is accept a parameter. We will visit the other two functions, g and sumVals, in turn.
let f x = x + 1 \\Single parameter, return given parameter + 1

Here we have a function named f. This function take a single parameter, x. Note that we do not specify the parameter's type explicitly. This forces the F# type system to try to figure out x's type based on context. Since F# sees that the function body sums x with the integer 1, it assumes that x must be an integer (since 1 is an integer). If we were to replace the 1 with 1.0, F# would assume x is a float. Notice that we have not defined a return type for the function. I'd like to make two points about this. First, instead of thinking about a function "returning" a value, it helps to think about a function "resolving to a value" or "evaluating to a value." (Although we still sometimes talk about a function returning a value, we really mean it resolved to a value). Second, F#'s type inference can generally deduce the type to which the function resolves. Of course, functions can have multi-line bodies. In the following example, we write a function that determines the minimum value of two inputs. This function is for demonstration purposes only. In a real-world implementation, we would implement this

more elegantly or, more likely, use the System.Math.Min() function.


let getmin a b = if a < b then a elif a > b then b else a

Note that we use whitespace to vertically align the function body. Remember that in F#'s #light mode (the only one we're using in this book), whitespace is significant, and is used to define semantically related code blocks. In some cases, F# may not be able to figure out the exact type of a function's arguments. The cause for this varies, but includes situations where the argument is part of an operation in the function body where one of several types is equally good. In the following example, we define a function countVowels that counts the numbers of vowels found in a given string. This is a contrived example, but is useful for making the point that sometimes we need to help out the F# type inference system:
\\Attemp #1: ERROR. F# cannot determine str's type. let countVowels str = let mutable vowels = 0 let lcs = str.ToLower() for i = 0 tolcs.Length - 1 do if str.[i] = 'a' || str.[i] = 'e' str.[i] = 'i' || str.[i] = 'o' str.[i] = 'u' then vowels <- vowels + 1 vowels

In the example above, F# cannot reliably determine the type of the parameter str, so it cannot compile the function. To assist F#, we need to explicitly define str's type. Here is the new, fixed function:
\\Attemp #2: OK. With addition of type into, F# can determine str's type. let countVowels (str : string) = let mutable vowels = 0 let lcs = str.ToLower() for i = 0 tolcs.Length - 1 do if str.[i] = 'a' || str.[i] = 'e' str.[i] = 'i' || str.[i] = 'o' str.[i] = 'u' then vowels <- vowels + 1 vowels

Notice the function signature. It now contains some added type information for the F# compiler to use. Here, we are explicitly stating that str is of type string. Once we do this, the function compiles fine. Observant readers may also have noticed the addition of parentheses around the parameter and it's type signature. When specifiying explicit types for function arguments, you must use the parentheses for F# to recognize the type properly, otherwise, based on precedence rules, it evaluates the intent incorrectly. We can use this same syntax for functions that accept multiple parameters as well. Below are a few examples:
let hyp (x:float) (y:float) = System.Math.Sqrt((x * x) + (y * y)) let marquee (s:string) (n:int) = for i = 1 to n do printfn "%s" s

byref Parameters
Sometimes you need to change function parameters, e.g., when interoperating with other .NET languages. To accomplish this in F#, you need to use a combination of mutable values, the address-of operator (&), and the byref keyword, as demonstated in the following example:
let incrementParam(i: int byref) = i <- i + 1 let mutable j = 10 incrementParam(&j)

In this example, we see that incrementParam's argument i in is of type int byref. The byref keyword tells the compiler to expect the address of a mutable value. In the next line, we use the mutable keyword so that when we pass j to incrementParam, the function can successfully change j's value. Lastly, when we call incrementParam, we supply the address of the mutable value, and we do so by using the address-of operator (&). Note that byref parameters work with value types such as primitives. We will look at more advanced data structures and how to pass and change them in subsequent chapters.

Function Types and the Weird Arrow Notation


The power of an F# function stems in large part from the fact that it can take one or more functions as parameters and return a function as a result. Before we can explore the nature and consequence of this idea, let's take a closer look at function types,

which will give us the background we'll need to delve more deeply. Like other expressions in F#, functions evaluate to a value, which means they have a concrete type. Let's take our simple example from above:
let f x = x + 1

When we define this function using theF# Interactive Console, we receive the following feedback:
val f : int -> int

This tells us that f is a function (indicated by the -> symbol, which I'll call the function symbol). This function takes a single integer paramter (parameter types are listed to the left of the -> symbol) and evaluates to an integer (the evaluation type is listed to the right of the -> symbol). This notation seemed very strange to me at first, until I realized why F# reports function types like this and it's back to the mathematical definition of a function. Remember that a mathematical function is really a tranformation. It transforms inputs to outputs in a reliable and regular manner. The function symbol ( ->) is therefore a very natural way to remind us what's happening the input is being transformed (or mapped) to an output of a given type. The rightmost value (the one to the right of the function symbol) is the final type of the function. In other words, it is the type to which the function evaluates. Take note that this notation is not a convenience, nor is it trying to be "especially F#-ish" or cerebral. It is a fundamental and important notation that reflects the nature and of the language. Becoming familiar with arrow notation will help you greatly in both learning and using F#. I made the mistake, at first, of thinking of it as "just another way to display what a function accepts and returns." This mind set made grasping some of the functional programming concepts more difficult than they should have been. I encourage you not to follow in my footsteps here. OK, let me hop off my soapbox and discuss another example:
let g(x) = x + 1 val g: int -> int \\Optional parentheses. Exactly same as g x = x + 1 \\F# reports this via the F# Interactive Console

Here, we've surrounded the parameter x with parens[1]. The only difference between f and g is that we used (optional) parentheses to clearly indicate that x is a parameter. Like f, g is a function that accepts a single integer as input and returns a single integer as output. Semantically, f and g are identical[2]. Now, let's discuss a slightly more complex example:
let sumVals x y = x + y \\apply operator + to values x and y val sumVals : int -> int -> int

Here we see that sumVals returns an integer (the right-most type following the last -> symbol). We can also see that it accepts 2 integer values as input (the first two ints listed from left to right). Given the above explanation of functions as transformations, you would probably assume that F# would display sumVals's type something akin to this: int, int -> int[3]. The reason F# displays sumVals's type as int -> int -> int is rooted in lambda calculus. In lambda calculus, all values, even constants, are represented as functions. Due to these underpinnings, F# functions only ever take a single parameter and return a single value. Although this doesn't appear to be the case due to syntactic sugaring in the language, F# enforces this idea conceptually[4]. If we now take the "lambda calculus view" of the sumVals function, we can think about its type as being the following:
int -> (int -> int)

The arrow symbol is right-associative, which means that you read it from right-to-left to discern it's meaning. Here, we start from the right and look at the two operands on either side of the -> symbol. The fact that the arrow is right associative means that we can put parens around the rightmost expression and preserve the original meaning, as we've done in this example. Here's where things get functional (and maybe confusing but bear with me and we'll work through it). This type tells us that sumVals is a function that takes an integer parameter (int ->) value and evaluates to (returns) a new function. This new function accepts a single integer parameter and, in turn, returns an integer. This is what (int -> int) means. To make things more confusing, invoking a function is left-associative. This means that we read function invocations from left-toright in order to group or associate elements. So, when we see a function definition like sumVals x y, semantically, it's the same as writing (sumVals x) y. Although this is not legal F# syntax for defining a function, it is legal syntax for invoking one. Breathe deeply. Repeat as necessary. Let's unravel this and see what it all means. We still have our function:
let sumVals x y = x + y

F# reports it's type as int -> int -> int. We will write it here as int -> (int -> int) to remind us what's really happening. Now when we invoke sumVals like this:
let sum = sumVals 10 20

It's as if we wrote it like this:


let sum = (sumVals 10) 20

In fact, this notation compiles perfectly.

Partial Function Application


What makes this all possible is that F# supports what's called partial application of functions. To "partially apply" a function, you only supply a subset of the arguments that the function expects. In other words, you don't pass in all the arguments at once. When you omit arguments, F# generates a new function that holds onto/remembers the arguments you passed in and "waits" for the other parameters to be supplied[5]. Let's run the following code in the F# Interactive Conole.
let sumvals x y = x + y \\Original function that we know and love let sumX = sumVals 10 \\Note: no 2nd param supplid. \\sumX is a new function generated from partially apllied sumVals. \\Another way to say this is that "sumX is a partial application of sumVals" let sum = sumX 20 \\Invokes sumX, passing in expected int (parameter y from original)

When we run the code above in the F# Interactive Console, F# reports back the following:
val sumVals : int -> int -> int val sumX : (int -> int) val sum : int = 30

When we call sumVals 10, F# sees that not all of the expected arguments were provided. In response, it generates a new function. This new function remembers the value of the parameter that was passed in (10), and generates code to add 10 to whatever is passed in next. In the example above, we capture this newly generated function and store it in sumX. We can now call, a.k.a., evaluate, sumX with an integer value, i.e., its expected argument. The code in sumX knows to add this value (20) to the original "held" value 10 and, voilla', we compute the sum (10 + 20 = 30). Let's look at a few more examples:
let sayHi = printfn "hi!"

This function appears to take zero parameters. In actuality, it takes a parameter of type unit. It also returns a value of type unit. Here is what the F# Interactive Console says when we run this function:
hi! val sayHi : unit = ()

Let's look at another function:


let f x s = printfn "%d %s" x s \\val f : int -> string ->unit

Here we see that this function, although it appears to accept two parameters, is really a function that accepts a single parameter of type int and returns a function that takes a single parameter of type string. This new function subsequently evaluates to the type unit. Based on this explanation, we could rewrite this function's type as int -> (string -> unit). Given the fact that F# functions only ever take a single parameter and return a single value, this "chaining" effect takes place regardless of the number of parameters. For example:
let f (a:int) (b:int) (c:int) (d:int) (e:int) = printfn "%A %A %A %A %A" a b c d e

Not surprisingly, the type of this function as reported in the F# Interactive Console is:
val f : int -> int -> int -> int -> int -> unit

Understanding that the function symbol -> is right-associative, we could re-write this type as follows:
val f : int -> (int -> (int -> (int -> (int -> unit))))

This tells us that function f accepts a parameter of type int and causes the generation of a function that itself takes an int, which,

in turn, generates a function that takes an int, etc. The final function evaluates to a value of type unit. The good news about all this? In most cases, you can simply read a function's signature from left-to-right and understand what types of arguments the function expects, and what type it returns (the right-most type displayed in the function's signature). So, what if you have a function that needs to accept multiple arguments, e.g., when you define a point and you need both the x and y coordintes? Enter our old friend the tuple. In order to pass in "multiple" values to a function, you can use simple (or more complex, as we'll see) collections like tuples. Since a tuple is a single entity, you are not violating the rule that F# functions only ever take a single parameter and return a single value. The following example ensures that the caller supplies both an x and a y coordinate for a point:
let translatePoint(x, y) = let newx = x + 100 let newy = y + 50 printfn "New point location = (%d, %d)" newx newy

As we learned earler, tuples are defined by surrounding comma-separated values with parens. translatePoint, therefore, does not accept 2 parameters, but accepts a single parameter of type tuple. Case in point, F# reports the type of this function to be:
val translatePoint : int * int -> unit

This tells us that translatePoint is a function (->) that takes as input a tuple of type int * int and evaluates to unit. Functions defined as taking a single tuple cannot be partially applied. In general, functions that accept one or more individual parameters (OK, we know that they only really accept one parameter but F# lets us think of them at taking multiple ones) separated by spaces is preferred, as they can participate in more advanced scenarios such as composition. We will cover more advanced uses of functions later in the chapter. Now that we know how to define basic functions, and know how to read F#'s function type notation, we are in an excellet position to explore additional functional concepts.

Nested Functions
F# supports defining functions within functions. We refer to these as nested functions or inner functions. Nested functions are typically used to encapsulate "helper" functionality inside the enclosing function. Because functional programs tend to execute loops via recursion, we sometimes need parts of functions to perform recursively to perform local looping. Using nested functions makes implementing "partial recursion" as straight-forward as possible. The following example was taken from the F# Wikibook (http://en.wikibooks.org/wiki/F_Sharp_Programming/Values_and_Functions#Nested_Functions) :
let sumOfDivisors n = let rec loop current max acc = if current > max then acc else if n % current = 0 then loop (current + 1) max else loop (current + 1) max let start = 2 let max = n / 2 \\largest let minSum = 1 + n \\1 and n loop start max minSum

(acc + current) acc factor, apart from n, cannot b > n / 2 are already factors of n

printfn "%d" (sumOfDivisors 10) \\print 18, because the sum of 10's divisors is 1 + 2 + 5 + 10 = 18

Notice that in this example, we define a function called loop, which is both nested and recursive (a common situation). We can see that sumOfDivisors calls loop (see last line) to perform the bulk of the computation. Certainly, the function loop could have been made external (not inner) and called from sumOfDivisors; however, by making loop a nested function, we are indicating a "more intimate" relationship between the outer function and its helper, and properly isolate the functionality where it belongs. In addition to demonstrting the relationship between functions, there is another benefit of using nested functions the nested function can access and use the values (variables, in case you've been yearning for that word for a while) defined in the outer function. This obviates the need for sumOfDivisors to pass n as a parameter to loop, as it would need to do if loop were made a regualr, non-nested function.

Key Functional Concepts


Remember from your high school or college days that mathematical functions obey strict mathematical rules. For example, functions can be used in standalone fashion, e.g., f(x), or they can be composed, e.g., f(g(x)). They can be also be defined recursively, can produce infinite sets of outputs, etc. Many of these concepts are directly reflected in functional programming languages; therefore, to really grasp and harness the power of functional programming, you need to understand a handful of functional concepts. Otherwise, the different mechanisms that we cover will feel nothing more than academic, and could result in frustration and confusion[6].

Recursion
The first functional concept that we need to become familiar with is that of recursion. In mathematics, and in programming, a recursive function is one in which the function being defined is applied within its own definition. To begin our discussion on recursion, let's use the tried-and-true factorial example. In F#, we define can define a recursive factorial function as follows[7]:
let rec factorial n = if n <= 1 then 1 else n * factorial(n-1)

Notice the new keyword rec. Whenever you define a recursive function in F#, you must use the rec keyword. Using the rec keyword does not change the function's fundamental type. As defined, our factorial function has type int -> int. Let's look at what happens when we call factorial:
let result = factorial 5 factorial 5 = = 5 * factorial (5 - 1) = 5 * 4 * factorial(4 - 1) = 5 * 4 * 3 * factorial(3 - 1) = 5 * 4 * 3 * 2 * factorial(2 - 1) = 5 * 4 * 3 * 2 * 1 = 120

Each time the function is called, the runtime allocates a new stack frame, inherently preventing side-effects, which is one of the goals of functional programming. In order to prevent infinite loops, all recursive functions must have a base case, which triggers termination. In the factorial example, the base case is where n is less than or equal to 1. When execution state satisfies the base case, this triggers termination and the stack unwinds normally. There are a few rules of which you should be aware regarding using a recursive functions. A recursive function must: have a base vase change its state and move towards the base case call itself, recursively (unless the initial condition satisfies the base case) I think the key to understanding recursion is to realize that a function calling itself is no different than, e.g., function A calling function B. The same exact processing occurs in both cases the runtime creates a new stack frame, the current instruction pointer and return address are stored, etc. There is nothing "magic" about the stack frame in the standard recursive case. The stack is the stack, and behaves exactly the same way in both the non-recursive and recursive cases. Due to the fact that recursive calls inherently prevent side effects, functional programming prefers recursion over imperative iteration structures. When defining recursive functions, you can define two recursive functions that call one another. These functions are called mutually recursive functions. The following example of mutually recursive functions was taken from Expert F# by Don Syme:
let rec even n = (n = 0u) || odd(n - 1u) and odd n = (n <> 0u) && even(n - 1u)

As you can see, the function even relies on the function odd, and the function odd relies on the function even. We define mutually recursive functions via the keyword and, as shown. One of the big issues inherent with recursion is the possibility of stack exhaustion, i.e., the system runs out of stack space. This can occur if the function requires too many iterations in order to reach the base case. The question that normally comes up here is, "If functional programming favors recursion, and recursion is subject to stack exhaustion, what's the use? How can I build real programs?" Good question. Enter tail recursion.

Tail Recursion
In standard recursion, the runtime needs to build up the stack, frame by frame, so that it can eventually complete its set of pending operations. Let's look at a conceptual diagram of calling our factorial function with the value 3:

Image 8.1: Recursion call and stack order

As you can see, the stack is built up, frame by frame, from the bottom up. The runtime needs to retain each stack frame in order to store information that it can use to perform the pending multiplications, e.g., 3 * factorial(2) and 2 * factorial(1). This means that the ultimate size of the stack is dependent upon the number of calls. If the number of calls is large, the stack will grow too large for available memory and kaboom stack overflow. We can eliminate this issue by writing our recursive functions using a tail recursion. A tail recursive function uses a special case of recursion in which the last instruction executed in the method is the recursive call there is no "pending operation" for the runtime to worry about. F# and many other functional languages can optimize tail recursive functions. Since no extra work is performed after the recursive call, there is no need for the function to remember where it came from or to store information about pending operations. F# optimizes tail-recursive functions by telling the CLR to drop the current stack frame before executing the target function. As a result, tail-recursive functions can call itself indefinitely without consuming stack space. To convert a standard (non-tail-recursive) function into a tail-recursive function, you need a way to eliminate the need for the pending operation. If you think about it for a second, what does recursion do? It "builds up" a result over one or more iterations. If we could somehow change the "building up" of the result and use another mechanism to eliminate the need for the runtime to allocate a stack frame per call, we could create a tail recursive function and avoid stack overflow. The standard solution is to use an auxiliary parameter. The following text was taken from this site (http://triton.towson.edu/~akayabas/COSC455_Spring2000/Recursion_Iteration.htm.) . I liked this explanation, and couldn't think of a better way to say it:

A non-tail recursive function can often be converted to a tail-recursive function by means of an "auxiliary" parameter. This parameter is used to build up the result. The idea is to attempt to incorporate the pending operation into the auxiliary parameter in such a way that the recursive call no longer has a pending operation.
To turn our standard recursive factorial function into a tail-recursive function, we need to introduce a value that builds up (a.k.a., accumulates) the answer as the function executes. Here is a tail-recursive version of the famed factorial function:
let rec factorial n result = if n <= 1 then result else factorial (n - 1) (n * result) \\Example call: factorial 5 1 will return 120

Note that this version does not contain a pending multiplication. Instread of the runtime needing to keep stack frames around so that it can eventually calculate the final result, we've used an accumulator to build up the result as we go. The key here is that the last thing the function does is call itself, thus avoiding any pending operation. The "last thing the function does" does not have to be lexically the last line of the function, although it often is. I like Wikipedia's description:

Note that the tail call doesn't have to appear lexically after all other statements in the source code; it is only important that its result be immediately returned, since the calling function will never get a chance to do anything after the call if the optimization is performed.
Some people don't like the "uncleanliness" of calling a tail recursive function with an extra accumulator parameter, so they will often provide a helper function that hides the accumulator from the call site. Here is an example of a "clean" tail-recursive factorial function that uses such a helper function to hide the fact that the accumulator exists:
\\Tail-recursive factorial function, includes accumulator let rec factorial n result = if n <= 1 then result else factorial (n - 1) (n * result) \\Helper function that hides the accumulator. This is the one colled by client code. let fact n = factorial n 1

Given the existence of the helper function fact, clients can use it as follows:

\\Client code example. Call the helper let result = fact 5

I hope that the previous discussion helps you to better understand recursion, and the ideas and implementation techniques behind tail recursion. We continue our exploration of functional programming concepts with high order functions.

High Order Functions


There is a lot of terminology that you need to master when you start living the functional lifestyle. One of the core concepts that you need to be familiar with is that of the high-order function. A high-order function is a function that either takes a function as a parameter or returns a function, a.k.a., evaluates to a function, as an output or does both. We saw a little of this when we discussed partial application of functions (which we will revisit again shortly). Since F# functions are just values, it's very easy to pass functions around. (If it helps, think about this as passing a pointer to some executable code). Let's look at a few examples. First, we'll define a function foo that takes as an integer n argument and a function f (yes, we will pass in a function). The function f will itself accept an integer as input and return an integer as output. The players:
foo = function that accepts two inputs an integer n and a function f n = the integer passed into foo f = the function that does something with n and itself returns an integer let foo (n:int) (f:int->int) = f(n)

We can then call this function with various combinations of parameters:


\\define some int ->int functions we can pass to foo let square n = n * n let cube n = n * n * n let cutInHalf n = n / 2 \\call foo with various combinations of input let x = foo 5 square let y = foo 5 cube let z = foo 5 cutInHalf

Running this code in the F# Interactive Console, we get the following output:
val square : int -> int val cube : int -> int val cutInHalf : int -> int val x : int = 25 val y : int = 125 val z : int = 50

Now, let's define another high-order function addone that returns a function. We can then use addone as an input to our beloved foo:
let addone = let f x = x + 1 f

\\define function to return \\return function

let foo (n:int) (f:int->int) = f(n) let result = foo 10 addone

High order functions are a staple of functional programming but as shown, they can be a little cumbersome to use. In order to have functions to supply to foo, for example, we fist need to define them, e.g., square and cube in our example. These functions exist solely so that we can pass them into foo. Wouldn't it be great if could by-pass defining these "side" functions and simply supply the functional code to foo directly? Well, it turns out that we can. This is the role of lambda functions.

Lambda Functions
I think the name lambda function sounds scary. It sounds complex. When I hear this term, I think of crazy-haired professors with thick glasses and white lab coats scribbling on dust- filled chalkboards.[8] I am happy (and relieved) to say, that lambda functions are nothing more than functions without names. Another term people use for them is anonymous functions. What possible use could a nameless function have?[9] Lambda functions are used in functional programming where you want to define or execute code in-situ. They are a convenient way to write code where you'd normally need to write a call to a helper function like square and cube in our previous example. If you're familiar with C# or Java, think "local event handler" or "anonymous delegate" or (in the latest version of C#) "lambda expressions."

You define a lambda function using the keyword fun. The fun keyword introduces the function. Lambda functions can accept input parameters and, of course, evaluate to a value (return output). The following example defines a lambda function called cube that returns the cube of the given input parameter:
let cube = fun n -> n * n * n

This function has no name. The symbol n following the keyword fun is a parameter not the name of the function. This example binds the identifer cube to the function code. Once bound, you can use the function like any other:
let cube = fun n -> n * n * n let c = cube 5

Running this code in the F# Interactive Console returns the following:


val cube : int -> int val c : int = 125

As you can see, there is fundamentally no difference between a lambda function and a normal F# function (look at cube's type, for instance). Note that lambda functions are a convenience. You can always implement the same code without using lambdas. Again, I refer you our previous foo example. Now that we know what lambda functions are, let's rewrite the example to use them:
let let let let foo x = y = z = (n:int) (f:int -> foo 5 (fun n -> n foo 5 (fun n -> n foo 100 (fun n -> int) = f(n) * n) * n * n) n / 2) \\f(n) = f n --- yout choice here

As you can see, we simply replaced the calls to the helper functions with lambda functions. Executing these lines of code yields identical results to the previous example. We will use lambda functions extensively in functional programming. Many of the builtin types and modules, e.g., List and Seq, define functions that accept function arguments. Most of the time, we supply these arguments in the form of lambdas.

Mapping
Now that we understand functions and their basic mechanics, let's start exploring their relatioships and usage patterns. Oneplace where functions are applied is called mapping. Mapping is the act of applying a function to each element of a list, and returning a new, same-sized list containing the results. In general, the guts of a mapping function takes the following form:
let map item converter = converter item

In essence, what we are doing here is applying a converter function to the given item. Mapping is prevalent when dealing with collections, e.g., arrays, list and sequences. Because we have not studied list or sequences yet, let's use arrays to illustrate how mapping works. To start, let's define an array of floats from 1.0-10.0.
let nums = [|1.0 .. 10.0|]

Now let's write a function called map that applies a given function to a given set of floating point values nums in our case:
\\Imperative implementation I dont't want to mix together recursion and \\mapping I am trying to present one topic at a time as not to confuse \\the discussion. let map fn (alist: float array) = let results = Array.zeroCreate<float> nums.Length for i = 0 to alist.Length - 1 do results.[i] <- fn(alist.[i]) results let roots map System.Math.Sqrt nums

As you can see here, the function System.Math.Sqrt is applied to each element of the given array, in turn. The result of each function application is stored in a results array, which is returned by this function. Mapping is such a common operation in functional programming that the F# libraries ship with efficient implementations. This means that we generally don't need to forge our own implementations. Let's take a look at the Microsoft.FSharp.Collections.Array (http://research.microsoft.com/enus/um/cambridge/projects/fsharp/manual/fsharp.core/Microsoft.FSharp.Collections.Array.html) class again, relative to what is offers in terms of mapping. This following table was taken directly from the Array documentation found on the Microsoft Research site: Array Operation val map : ('T -> 'U) -> 'T array (h p://research.microso .com/enDescription Build a new array whose elements are the

us/um/cambridge/projects/fsharp/manual/fsharp.core/Microso .FSharp.Core.type__array-1.html)->

'U array (h p://research.microso .com/enus/um/cambridge/projects/fsharp/manual/fsharp.core/Microso .FSharp.Core.type__array-1.html)

results of applying the given func on to each of the elements of the array. Build a new collec on whose elements are the results of applying the given func on to the corresponding elements of the two collec ons pairwise. The two input arrays must have the same lengths, otherwise an ArgumentException is raised. Build a new array whose elements are the results of applying the given func on to each of the elements of the array. The integer index passed to the func on indicates the index of element being transformed. Build a new collec on whose elements are the results of applying the given func on to the corresponding elements of the two collec ons pairwise, also passing the index of the elements. The two input arrays must have the same lengths, otherwise an ArgumentException is raised.

val map2 : ('T1 -> 'T2 -> 'U) -> 'T1array (h p://research.microso .com/enus/um/cambridge/projects/fsharp/manual/fsharp.core/Microso .FSharp.Core.type__array-1.html)->

'T2 array (h p://research.microso .com/enus/um/cambridge/projects/fsharp/manual/fsharp.core/Microso .FSharp.Core.type__array-1.html)->

'U array (h p://research.microso .com/enus/um/cambridge/projects/fsharp/manual/fsharp.core/Microso .FSharp.Core.type__array-1.html)

val mapi : (int (h p://research.microso .com/enus/um/cambridge/projects/fsharp/manual/fsharp.core/Microso .FSharp.Core.type__int.html)-> 'T ->

'U) -> 'T array (h p://research.microso .com/enus/um/cambridge/projects/fsharp/manual/fsharp.core/Microso .FSharp.Core.type__array-1.html)->

'U array (h p://research.microso .com/enus/um/cambridge/projects/fsharp/manual/fsharp.core/Microso .FSharp.Core.type__array-1.html)

val mapi2 : (int (h p://research.microso .com/enus/um/cambridge/projects/fsharp/manual/fsharp.core/Microso .FSharp.Core.type__int.html)-> 'T1 -

> 'T2 -> 'U) -> 'T1 array (h p://research.microso .com/enus/um/cambridge/projects/fsharp/manual/fsharp.core/Microso .FSharp.Core.type__array-1.html)-> 'T2 array (h p://research.microso .com/enus/um/cambridge/projects/fsharp/manual/fsharp.core/Microso .FSharp.Core.type__array-1.html)-> 'U array (h p://research.microso .com/enus/um/cambridge/projects/fsharp/manual/fsharp.core/Microso .FSharp.Core.type__array-1.html) Table 8.1: F# Array Operation

Don't worry about the 'T and 'U notation for the moment. This is F#'s notation for generics, which we'' will cover soon. For now, mentally replace 'T with integer and 'U with integer or float or a concrete type with which you're comfortable. To see how these functions work, let's create an Array to hold the original values that we'll map against. Instead of using zeroCreate to create our Array, we will use the more flexible init method, which enables us to create and initialize the array using a lambda function. Note that most of Array's interesting functions are defined on the class itself (are static), and we access them via the Array.method syntax. On to the example:
\\Create an array 0..9 using a lambda function to initialize the element let nums = Array.init 10 (fun n -> n)

Now that we have an array, we can apply a function to each element. Let's compute the square of each element this time:
\\Apply square function to each element of nums let square = Array.map (fun n -> n * n) nums

Notice here that we are applying a lambda function, whereas in the previous example, we applied a standard .NET function (System.Math.Sqrt). It doesn't matter to F# whether the function is a lambda function or a standard function it's "all functions" as far as it's concerned. Something to note: the function you apply must be compatible with the target. In other words, if we were to replace fun n -> n * with another function one that expects, say, floats, like System.Math.Sqrt, F# would complain that it couldn't apply a function that expects a float to a value of type integer.
n

Let's finish off this section by providing examples of using Array's various mapping functions. At their core, these functions all apply a conversion function to their input list and produce a new, resulting list. In F#-ese:
\\Create an array of 6 evens, 0, 2, 4, 6, 8, 10 let evens = Array.init 6 (fun n -> n * 2) \\Create an array of 6 odds let odds = Array.init 6 (fun n -> (n * 2) + 1) \\Sum up the evens and the odds let sums = Array.map2 (fun a b -> a + b) evens odds val evens : int array = [| 0; 2; 4; 6; 8; 10 |] val odds : int array = [| 1; 3; 5; 7; 9; 11 |] val sums : int array = [| 1; 5; 9; 13; 17; 21 |] \\Create an array of 6 evens, 0, 2, 4, 6, 8, 10 let evens = Array.init 6 (fun n -> n * 2) \\Cube the 3rd (index = 2) element, zero out all the rest let cube4 = Array.mapi (fun index n -> if index = 2 then n * n * n else 0) evens val evens : int array = [| 0; 2; 4; 6; 8; 10 |] val cube4 : int array = [| 0; 0; 64; 0; 0; 0 |]

\\Create an array of 6 evens, 0, 2, 4, 6, 8, 10 let evens = Array.init 6 (fun n -> n * 2) \\Cube every other element, 0 out the others let cubes = Array.mapi (fun index n -> if index % 2 = 1 then n * n * n else 0) evens val evens : int array = [| 0; 2; 4; 6; 8; 10 |] val cube4 : int array = [| 0; 8; 0; 216; 0; 1000 |]

Folding
The next functional concept that we need to be familiar with is that of folding. Folding is the act of processing a data structure in some order as to calculate a single return value. Generally, the implementation of a folding function is recursive. Typically, folding deals with a collective data structure, e.g., an array, list or tree, and a combining function, e.g., addition or merging. The combining function is applied is some systematic way to the structure, building up a single return value as it goes. This return value is often referred to as an accumulator, since it's used to accumulate the results as the operation proceeds. Because folding is a such common operation performed in functional programs, many of F#'s data structures ship with folding methods. Let's look at a simple example method from Array.
\\Sum the integer 0-9 let nums = Array.init 10 (fun n -> n) let sum = Array.fold(fun acc element -> acc + element) 0 nums

The first line of code creates an Array that holds the integers 0-9. The next line uses Array.fold to apply a function to each element. Here again we see lambda functions, a.k.a., lambdas, used. The first parameter to the lambda, acc, is the accumulator the value used to build up the final result. The second parameter is the nums array, the collection over which the lambda is applied. The 0 parameter is the accumulator's initial (seed) value. Folding, also known as reducing or consuming, comes in two flavors: folding left and folding right. Folding left means your operations begin at the left-most element and work their way right. In other words, they consume the elements from left to right. Folding right means starting from the right-most element and working towards the left. The decision to fold left or fold right has a dramatic impact when either the data structure under consideration is non-linear, like a binary tree, for example, or when the function applied to the data structure is non-commutative, e.g., division or subtraction. In other words, order usually matters. Note that the initial value supplied to a fold (either left or right) is always the first value used when the folding begins. A slightly more mathematical way to describe left and right folding is illustrated below:

Folding left: If the input function is f and the elements are i0iN, left folding computes: f ( (f s i0)) iN. Here, s is stands for "state", which is another way to think of the accumulator. If we consider our previous example, a left fold can be thought of as:
(((((((((0 + 0) + 1) + 2) + 3) + 4) + 5) + 6) + 7) + 8) + 9 = 45

Folding right: If the input function is f and the elements are i0iN, right-folding computes: f i0((f iN s)) . Here again, s stands for "state", which is another way to think of the accumulator. If we again consider or previous example, a right fold can be thought of as:
0 + (1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + 0)))))))))

Before we look at another example, it's worthwhile to quickly visit the fold function's type as documented at Microsoft Research and via Intellisense. See if you can decipher it if you can can, congratualtions - it's confusing!
val it : (('State -> 'T -> 'State) -> 'State -> 'T array -> 'State)[10]

This type signature tells us is that fold is a function that takes 3 parameters and returns a value (the right-most 'State).
fold's first parameter is a function. Let's call this the lambda function. The lambda function is of type ('a -> 'b -> 'a) and itself accepts 2 input parameters, an accumulator or state (the first 'State) and a value of some type ( 'T). The lambda returns a value that is type-comptible with the first parameter (the second 'State). In terms of the fold function, thi means that the accumulator and the return value of the lambda function have the same data type. fold's second parameter is an initial state (seed value of the accumulator) (the third 'State). fold's third parameter is the array to fold ('T array). fold returns a value that has the same type at the accumulator. (The first 'State and the last 'State, by definition, are of the same type).

In the next example, we create an array containing the integers 0-4. We then fold the list left, using addition, and fold the list right, using subtraction. The F# Array class names the right fold foldBack. Notice that fold and foldBack take their seed and list

values in the opposite order.


let nums = Array.init 5 (fun n -> n) \\0-4 let sum = Array.fold(fun acc element -> acc + element) 0 nums \\sum = 0 + 0 + 1 + 2 + 3 + 4 = 10 let diff = Array.foldBack(fun element acc -> acc- element) nums 0 \\diff = 0 - 4 - 3 - 2 - 1 - 0 = -10

Note that when you look at the documentation for the Array type, you may notice that Array supports both a fold family of methods as well as a reduce family of methods. The only difference between these methods is that with fold you can supply an initial accumulator value, whereas with reduce, you cannot. With reduce, the accumulator starts at 0. You can also use Array's scan and scanBack methods to obtain the intermediary results as well as the final, folded value, as in the following example:
let nums = Array.init 5 (fun n \\0-4 let foldl = Array.fold(fun acc \\foldl = 10 let scanl = Array.scan(fun acc \\scanl = [|0; 0; 1; 3; 6; -> n) element -> acc + element) 0 nums item -> acc + item) 0 nums 10|]

Unfolding
Akin to folding, functional programming supports the concept on unfolding. Unfolding means generating a list or sequence of elements from an initial value, using a function. While Array does not support unfolding, F# ships with data structures such as List and Seq (sequence) that do. We will look at unfolding more closely when we study these structures.

Filtering
We are fast becoming steeped in functional concepts. Stick with me for a little while more, and you will be in a great position to not only get the most out of the rest of this book, but will be able to read and understand a good amount of the mainstream[11] functional programming literature. We take this opportunity to move on to filtering.

Filtering is the process by which you apply a function to each element of a collection, keeping the ones you want and discarding the others. The function you apply to the elements must evaluate to true or false a Boolean. Functions like these - that evaluate to true or false - are called predicates. When you apply a predicate to an element in the collection, if the predicate evaluates to true, the element under consideration is appended to a new results collection. If the predicate evaluates to false, the element is skipped. This process continues until the predicate has been applied to all of the original elements. Note that filtering does not affect the original list (remember, functional languages don't like side effects).
Of course, Array implements a filter method. Let's take a look at an example:
let nums = Array.init 100 (fun n -> n) let evens = Array.filter(fun item -> item % 2 = 0) nums let big = Array.filter(fun item -> item >= 50) nums \\0-99 \\evens \\ 50

Zipping
While "zipping" is not a term your hear bandied about in functional programming, the concept surfaces often enough to warrant a quick discussion. Zipping is the process of combining two lists together pair-wise (like how the teeth of a zipper come together, sort of). Let's take the following two arrays as an example:
\\nums = 0-9, sqrt = squares of 0-9 let nums = Array.init 10 (fun n -> n) let sqrs = Array.init 10 (fun n -> n * n)

To pair up (or "zip together") numbers ( nums) with their squares (sqrs), you can use Array's zip function:
let z = Array.zip(nums) sqrs val z : (int * int) array = [|(0, 0); (1, 1); (2, 4); (3, 9); (4, 16); (5, 25); (6, 36); (7, 49); (8, 64); (9, 81)|]

The Array class, among other collections classes such as List and Seq, supports a small family of zip functions.

Pipelining |>
Now that we understand functions and how to work with them, let's explore F#'s pipeline operator (|>), arguably one of the most important operators in the language. The pipeline operator (sometimes referred to as the forward operator) enables us to pass a value into a function in a natural manner. Let's look at a simple example to start:
letf x = x * 2 letr1 = f 10 letr2 = 10 |> f

In the first line of this example, we define a function f that takes a single argument x and returns x * 2. The second line demonstates a traditional call site, whereas the third line demonstrates the use of the |> operator the value 10 is provided as (or "forward to" or "pipelined into") f as its first parameter. The |> operator is often used to build a chain of processing, that enables us to express program logic in the sequence in which we think about it. Let's look at a slightly more complex example:
let let let let let a b c d e x x x x x = = = = = x x x x x + + + + + 1 2 3 4 5

let r1 = a(b(c(d(e(100)))))

Using the pipeline operator, we can write this example a bit more elegantly and clarify what's happening:
let r2 = 100 |> e |> d |> c |> b |> a

The pipeline operator is defined as follows:


let inline[12] (|>) x f = f x

As defined, the pipeline operator is a binary operator, meaning that it expects two inputs: a value and a function (val |> func). As we can see from the body of the operator's implementation, the operator applies the given function to the given value (func val). This simplicty turns out to be very useful and poweful and provides a mechansim with which we can express algorithmic intent naturally. The pipeline operator is especially powerful when dealing with lists and sequences of values. It enables us to quickly and naturally apply a chain of ordered operations on each element of a collection. We will see examples of this when we study lists and sequences. Using the pipeline operator vs. calling functions with paramters has a few advantages, namely clarity and improved type inference. The |> operator support the flow of type information from input objects to the functions that act on them. Note that the pipeline operator only works with functions that support partial application. Remember that your function supports partial application if it accepts multiple inputs separated by spaces vs. a function that forces the caller to supply a tuple as an argument. One more example should whet your appetite for using the pipeline operator. In the following example, we tap into the .NET libraries to capture all of the processes running on a machine and filter out those with the name "taskeng" (since I have a bunch of those running):
let processes = System.Diagnostics.Process.GetProcesses() |> Array.map(fun a -> a.ProcessName) |> Array.filter(fun a -> a <> "taskeng") val processes : string array = [|"OfficeLiveSignIn"; "iexplore"; "explorer";"cvpnd"; "rundll32"; "smax4pnp"; . . . "MSASCui"; "wmpnetwk"; "System"; "IAANTmon";"Idle"|]

Some of the process names were removed from the above listing for brevity. Note that F# also supports the backward pipe operator (<|) operator, used far less frequently than the forward pipe operator( |>). It passes the expression on the right side to the function on the left side.

Function Composition
A common operation in which mathematical (and programmatic) functions participate is composition, e.g., f(g(x)). F# supports function composition via the function composition operator (>>). Function composition enables us to design low-level, granular functions and piece them together in various ways to form more complex structures.
let let let let f x = x * x g x = x + 1 h = f >> g result = h 5 \\square the input \\increment the input square then increment 26; same as 5 |> f |> g

The function composition operator is defined as follows:


let (>>) f g x = g(f(x))

The >> operator is a binary operator. It accepts 2 function parameters, f and g. The final argument,x, is usually supplied later on, as in our example that defines the function h (above).

Note that F# defines a sister operator << that enables us to combine functions in the reverse direction, e.g., g << f is the same as saying f >> g. To be honest, I am not sure of its value or utility outside of writing obscure code such as: let result = f >> g << h (which is the same as writing (f >> g) << h due to F#'s associativity rules). Use this construct sparingly, as its makes your code difficult to understand (IMHO).

Partial Application and Currying


Earlier in this chapter, we saw examples of partially applying functions. For completeness, I'd like to take a moment and review partial function application and describe it in the context of another, related concept called currying. Mathematically, currying is the concept of deconstructing a function of multiple parameters into a composition of several functions all of arity 1. This means that a function taking multiple parameters can be represented by a combination of multiple functions each taking a single parameter. When we call a multi-argument function with fewer arguments than it expects, we are partially applying the function and, in return, receive a function that accepts 1 fewer parameter F# curries the original function and returns to us one that expects 1 fewer parameter. For example:
let f x y = x * y let g = f 2 let result = g 4

Here, f is a function that takes 2 parameters, x and y. g is a function that results from calling f with 1 of its 2 expected parameters. In other languages, like C#, this would result in a compilation error. In F#, however, calling f in this way, a.k.a., parially applying f, results in a new function, which we capture in g. The new function, g, takes the remaining parameter as input. In the last line of this example, we invoke g with a parameter of the expcted type. At the end of the day, the distinction between partial application and currying is not particularly important, especially from the pragmatic point of view of F#. Whether you are "partially applying" or "currying" is largely academic. The two concepts go handin-hand. That said, the fundamental concept of being able to call functions with a subset of argments, and have new functions returned, is an important characteristic of functional languages, and is used to provide powerful, useful and elegant constructs like function composition and pipelining.

Closures
For some reason, the term closure always used to cause me anxiety. I don't know why. I think it's because, as a visual learner, I tried to picture what a closure is, and I couldn't quite do it until it "clicked". For all those visual learners out there, I'm going to do my best to help define what closures are, and demonstrate why they are useful constructions. A closure is a function with some values attached. Let's illustrate this using an example inspired by this article (http://www.defmacro.org/ramblings/fp.html) :
let makePowerFn power = let powerFn b = b ** power powerFn let square = makePowerFn 2.0 let result = square 3.0; \\returns 9.0

In this example, makePowerFn accepts a single parameter, power, and uses it to create a new function, powerFn, which is returned to the caller. The newly created function has one variable whose value is fixed or closed. The other variable, b, which represents the base number (the one that will get raised to the given power) is called a free variable, since it is still not bound to a value yet. It will only be bound to a value when the function is called. A free variable, in other words, is a variable awaiting substitution (being bound to a value sometime in the future). So, when we invoke square 3.0 above, how can it work? F# must somehow store the value of power (in this case 2.0) in order for the function to execute properly. The entity that contains power bound to 2.0 is called a closure. As you can see from this example, partially applying a function in F# results in a the formation of a closure. I really like the explanation of closures found here http://ruby.dzone.com/articles/introduction-functional (http://ruby.dzone.com/articles/introduction-functional) . To paraphrase:

Closures are common in a variety of programming languages today. Closures are dynamically allocated data structures containing a code pointer, pointing to a fixed piece of code computing a function result and an environment of bound variables. A closure is used to associate a function with a set of "private" variable.
The following diagram illustrates the idea:

Image 8.2: Function with partial parameters as Closure

The MSDN documentation here (http://msdn.microsoft.com/en-us/library/dd233186(VS.100).aspx) , helps us to understand when F# forms closures:

Closures are local functions that are generated by certain F# expressions, such as lambda expressions, sequence expressions, computation expressions, and curried functions that use partially applied arguments. The closures generated by these expressions are stored for later evaluation.
As you can see, closures are an important idea they enable F# and other functional programming languages to support highorder functions, partial application, currying, etc.

Continuations
Yet another functional concept with which you should be familiar is that of continuations. A continuation is a mechanism by which the system can freeze the state of a function (or entire program) and resume it at some point in the future. When the function returns to the original caller, it preserves the state of its local variables. If you are familiar with C# iterators, a.k.a. generators, you get the idea of a continuation. In F#, continuations manifest themselves in the form of sequences (Seq), which we will study later. Note that continuations are closely related to and form the basis of a style of programming called Continuation Passing Style or CPS. In this style of programming, functions do not return values per se, but pass their results on to the next function in a chain. Let's look at a simple example. First, we'll define a few functions and illustrate a typical call sequence:
let mul x y = x * y let addone x = x + 1 let m = mul 3 5 let a = addone m

After mul is called, m contains the return value, which is subsequently passed in to the addone function. If we were to re-write these two calls in CPS style, we would add another parameter to mul a function that accepts the results of the multiplication and continues the calculation. Here is the same example written in a CPS style:
\\Function that must apply the supplied \\function fn when done with its work let mul x y fn = fn (x * y) \\The continuation function let addone n = n + 1 \\Capture the final result let result = mul 3 5 addone

Now mul takes one extra parameter a continuation function and applies it when it's done with it own calculation. If we wanted to extend the continuation, we could add a continuation function parameter to addone as well, ad infinitum. Programs written in CPS style favor functions with continuation parameters vs. creating long sequences of stack frames. Continuations are useful for storing function or program state and "continuing" the program or function sometime in the future again, iterators and generators are common examples. Continuations are first-class citizens in some functional programming languages like Scheme and cross-over languages like Ruby. A thorough coverage of continuations is beyond the scope of this book, but you have enough of a flavor of what they are what they do to appreciate and understand them.

Lazy Evaluation
Another interesting and useful construct we use in functional programming is lazy evaluation. Lazy evaluation, in contrast to the default eager evaluation, enables us to delay the execution of a computation until the results are actually needed. In order to take advantage of lazy evaluation, we use the keyword lazy keyword around the expression we want to delay. Using the lazy keyword tells F# to delay the computation. "Until when?" you might ask until you explicitly force the evaluation using the Lazy.Force function defined in the Microsoft.FSharp.Control.Lazy (http://research.microsoft.com/enus/um/cambridge/projects/fsharp/manual/FSharp.Core/Microsoft.FSharp.Control.type_Lazy-1.html) namespace. When you call force on a particular lazy expression, the value is computed and the results are cached using a specific memoization (http://www.answers.com/main/ntquery?s=memoization&gwp=16) technique. This causes subsequent calls to the Force function to retrieve and use the cached value, whatever it is, even if this means raising an exception. The following example shows the basic syntax and concepts behind lazy evaluation:

syntax and concepts behind lazy evaluation:


let square x = lazy(x * x) let calc = square 5 \\lazy expression \\calc unevaluated

val square : int -> Lazy<int> val calc : Lazy<int> = <unevaluated>

As you can see, the F# Interactive Console reflects the fact that calc refers to a lazy calculation and is not yet evaluated. To force evaluation, we use the Lazy.force function:
let answer = calc.Force()

Now that we've called force once for this lazy expression, F# has cached (memoized) the value. Subsequent calls will retrieve the cached value. While this example demonstrates the fundamental idea, it fails to answer the oft-posed question, "Does lazy evaluation has any practical applicability? I mean, if you need the value from a computation, why bother making it lazy only to force it later on?" Lazy evaluation makes possible the creation of lazy data structures. F#, for example, supports lazy lists and lazy sequences. They are lazy in the sense that they only compute their elements when needed, e.g., when the elements are needed by the program. If we take these types of data structures to their logical limits, we can see that lazy evaluation enables to creation of lists and sequences that hold an infinite number of items. This is not possible to do with traditional collection structures. In addition, lazy evaluation makes certain types of behind-the-scenes optimizations possible. A compiler that understands "lazy semantics" can rearrange code for more efficient execution, compile away or optimize branches, etc. Lastly, since you only pay for what you use, lazy evaluation can speed up program execution. For instance, imagine a scenario where you have an ifthenelse clause, where the else expression consists of an expensive computation that only occurs once in a great while. In this case, you would make the else expression a lazy expression and force its execution only when the code path dictated it. Subsequent calls through the else clause would use the cached value, increasing overall throughput.

Operator Overloading
Since it is so closely related to functions, the last topic we'll cover in this chapter is operator overloading. To understand operator overloading, you first need to understand that F# implements operators simply as functions functions with odd, symbol-based names (remember when Prince changed his name to a symbol?). You can define new or overload operators on records and classes, as well as in the global namespace. Since we've not covered records or classes yet, let's demonstrate both overloading an existing operator (generally a bad idea), and creating a new operator in the global namespace. But, first, a word from our MSDN sponsors on the rules (http://msdn.microsoft.com/en-us/library/dd233204(VS.100).aspx) :

You can overload all the standard operators, but you can also create new operators out of sequences of certain characters. Allowed operator characters are !, $, %, &, *, +, -, ., /, <, =, >, ?, @, ^, | and ~. In addition, : is permitted, but not as the first character. The ~ character has the special meaning of making an operator unary, and is not part of the operator character sequence.
When overloading an operator (or creating a operator using the rules as specified above), we use the general form:
\\Overloading an operator at the global level let [inline] (operator-symbols) parameter-list = function-body

which is optional, tells the compiler that "this is a short method that should be expanded at the call site vs. generating a function and a call at the call site." Use inline judiciously, as you can introduce code bloat. The symbols that define the operator appear in parens, and depending on the operator type unary or binary the operator takes one or more parameters. The function-body performs the work. In our first example, we override integer addition:
let (+) (x: int) (y: int) = x + 2*y

inline,

Now when we add two integers, this overloaded operator (function) gets called:
let result = 5 + 6 \\17 vs. 11

When F# resolves this function, it finds an overloaded instance in the global namespace that matches the infered types (5 and 6 are integers) and selects it for exection. Since F# invokes our overloaded operator, the result of the addition is 17 vs. 11. As you can see, when you overload existing operators, you run the risk of introducing confusion so be careful with your new found power. Not as risky, but worth considering carefully, is introducing a new operator into the mix. You many want to do this for brevity or cognitive clarity, in particular in specialty applications like engineering, mathematics, data processing, etc. For illustrative

purposes, we will define a simple unary (we know it's unary because we use the special symbol ~ to make it unary) operator that takes a number n (a float) and returns it's reciproal ( 1.0 / n):
let(~!) (n : float) = if n <> 0.0 then 1.0 / n else nan

\\"not a number", defined in .NET libraries (System.Double)

Once defined, applying the operator is simple:


let oneTenth = ~!10. val oneTenth : float = 0.1

We can also introduce binary operators. The following operator takes two integers and computes their greates common divisor (the largest integer number which evenly divides into two other integers):
let rec (^%) x y = if y = 0 then x else (^%) y (x % y)

Note that the operator is recursive, demonstrating a useful factoid that operators are nothing more than functions with irregular names. To build this operator, in fact, all I did was to take a standard function, previously named gcd, and replaced the name gcd with the operator symbols. Now I can apply the operator naturally:
let gcdResult = 123 ^% 456 \\3

We will look at operator overloading in the context of records and classes upon discussing these topics in a later chapter.

do Bindings
Let's conclude this chapter by discussing do bindings, which are nothing more than a way to execute code outside the context of a function or let expression. I chose to introduce do bindings here to show how code can be exectued outside the context of any function. A do binding takes the following form:
[ attributes ] [ do ]expression

The expression in a do binding must return unit. Code in a top-level do binding is executed when the module[13] is initialized. The keyword do is optional (which is odd, since the name of the constructs includes the word "do.") Attributes can be applied to a top-level do binding. For example, if your program uses COM interop, you might want to apply the attribute to your program. You can do this by using an attribute on a do binding, as shown in the following example adapted from the MSDN documentation:
STAThread open System open System.Windows.Forms let form1 = new Form() form1.Text <- "XYZ" [<STAThread>] do Application.Run(form1) // access .NET System namespace (covered later) // access forms namespace // // // // // create a new Form change window caption running in single-threaded apartment "do something" the thing to do

That's really all there is to the do binding. We will revisit it again in Chapter 16, when we specifically discuss namespaces and modules.

Project Euler
Now that we have studied functions, you may want to look at an interesting project called Project Euler (http://projecteuler.net/) . From the website, we learn that:

Project Euler is a series of challenging mathematical/computer programming problems that will require more than just mathematical insights to solve. Although mathematics will help you arrive at elegant and efficient methods, the use of a computer and programming skills will be required to solve most problems. The motivation for starting Project Euler, and its continuation, is to provide a platform for the inquiring mind to delve into unfamiliar areas and learn new concepts in a fun and recreational context.
Many people have taken up the Project Euler challenge and have solved the problems using F#. At this point in the material, you are well on your way to being able to read and understand some of the solutions. By the end of the book, you'll be in a position to tackle many of the problems yourself!

What You Need to Know


Congratulations! You made it through a long, tough chapter filled with lots of new ideas and techniques. Understanding the terminology from this chapter will help you a greatly in understanding and appreciating the rest of the material in this book. Functions are values and have strict types, represented using typeA -> typeB, etc. Functions can be nested. Nested functions help abstract and encapsulate complex sub-sections of the function body. High-order functions are those that can accept functions as arguments and can return (resolve to) functions as output values. In F#, you can call functions and omit one or more arguments. This is called partially applying a function. When you partially apply a function, F# generates a new function (using a closure) that stores the bound variables and contains a list of the remaining free variables (the ones you omitted in the first place). F#, like its functional cousins, prefers recursion to imperative loops. Recursion can lead to stack exhaustion, if you are not careful. One common technique that helps prevent stack exhaustion is tail recursion, where you write your code in such as way as to prevent operations from needing to occur at or after the recursive call site. F# supports lambda functions which are functions with no name. These are sometimes called anonymous functions. Common functional operations that you see in F# and other functional languages include mapping, filtering, folding and zipping. F# uses the pipeline operator |> to send the results of an expression as input to another expression. F# uses the >> to compose functions (build up more complex functions from more primitive ones). Currying is a technique whereby F# takes a function with multiple arguments and turns it into a series of functions each taking a single argument. Currying and partial application are generally discussed in tandem. They are not the same thing. Closures are structures that have their own set of private, bound variables, one or more free variables, e.g., function parameters, and a function. They are created by F# in several cases, one of which is when you partially apply a function. We will look at other cases later. Continuations are structures that save state which can be retrieved and used in the future. Iterators and generators are examples of continuations. Lazy evaluation, a.k.a., deferred execution, is a technique for delaying a calculation until it's actually needed. F# uses the lazy keyword in tandem with the Lazy.Force function to implement lazy evaluation.
[1] [2]

From here on in, I may use the programmer-accepted slang term parens as a shortened form of parentheses. Note that the functions being semantically identical only applies to single-parameter functions. As we will see, when your functions have two or more parameters, the use of parenthesis, while still optional, changes the semantics. [3] At least, that's what I would have expected. [4] I say conceptually because for optimization reasons, F# may bypass true function generation in favor of a more expedient imperative implementation. See FastFunc<> for details. [5] The structure that "remembers" the supplied parameters is technically referred to as a closure. We will cover closures later in this chapter. [6] I know this all too well. When I first tried learning functional programming, most of the texts went straight to the programming constructs I had no idea what anything meant. In part, my experiences motivated me to share what I've learned in this book. [7] This implementation allows inputs < 0, which is technically not allowed for factorials. I use this implementation for simplicity only, as it works correctly for n >=0 and enables us to discuss recursion. [8] If you are not old enough to know what a real chalkboard is, I can't help you there. [9] Although I hear a horse with no name can get you through the desert. [10] Remember that F# uses 'T and the like to express generics. We will cover generics in another chapter. [11] OK, so "mainstream" may be a bit optimistic at this point; however, I think we will see a dramatic spike in the interest and use of functional programming languages in the next 3-5 years. [12] Inline functions are functions that are integrated directly into the calling code. It is an optimization suggestion to the compiler. [13] We will discuss modules and packaging in a later chapter.

Chapter 9 Generic Functions


Introduction
The idea of type is fundamental to programming. A variable's type governs the values that the variable can hold, and the operations in which it can participate. In strictly typed languages, type is determined at compile time, and the compiler enforces strict value and operational constraints. In general, this strict type checking is valuable in that it prevents accidental misuse of a variable, and enables the compiler to generate efficient code. Sometimes, however, strict type checking can get in the way of expressiveness and flexibility. When we develop algorithms, we tend to think about them in a type-free manner. In other words, we tend to abstract them from type and think about them generically. A classic example is sorting. It doesn't make a difference if we are sorting integers, strings, or FileInfo objects the idea of putting "things in a given order" is an abstract idea that applies to many different kinds of entities. Generics enable us to model data structures and algorithms in a type-agnostic way. They allow for the definition of structure while deferring type specifics.

F# Generic Functions
Systems that support generics use a type placeholder for the eventually specified concrete type or types. In other words, a generic type represents a type to be specified later. F# uses '<identifier> syntax to specify a type placeholder. We see this illustrated in the following example:
let first(a, b, c) = a val first : 'a * 'b * 'c -> 'a

Here, the F# type inference system has determined that the function first takes a 3-member tuple, each element potentially of a different type. 'a is the first type placeholder, 'b the second, and 'c the third. These may all be different types. We can see from this definition that the function evaluates to a type of 'a. The following is paraphrased from the MSDN documentation on F# generics (http://msdn.microsoft.com/enus/library/dd233215(VS.100).aspx) :

In F#, functions, methods, properties, and aggregate types such as classes, records, and discriminated unions can be generic. Generic constructs contain at least one type parameter. Generic functions and types enable you to write code that works with a variety of types without repeating the code for each type. Making your code generic can be very simple in F#, because often your code is implicitly inferred to be generic by the compiler's type inference and automatic generalization mechanisms.
What does all this mean? In a nutshell, F# will attempt to make your structures generic, unless there is a reason it cannot. This enables and promotes code clarity, succinctness and reuse.

Automatic Generalization
When F# determines the type of a value, function or data structure, it looks at context such as function parameters, the function body, how parameters are combined in operations, etc. If F# determines that the operations, etc., are independent of type, it will automatically apply generic typing to the function at hand. We saw an example of this in the example above. The compiler performs automatic generalization only on complete function definitions that have explicit arguments, and on simple immutable values. Note that if you explicitly specify a type in your function parameter list or within the body of the function, you prevent automatic generalization on that value; however, F# can still apply automatic generalization to the other parameters and values.

Making Functions Generic


Due in large part to automatic generalization, when you write a function (or other construct), you can largely ignore explicitly spelling out that parameters, etc. are generic. If you run into a situation where you need to do this, F# supports this capability. In the following example, we write two swap functions. In the first case, F# determines swap to be generic. In the second case, we tell F# that swape is generic.
let swap(a, b) = (b, a) let swape(a:'a, b:'b) = (b, a)

Both of these functions, swap and swape (e for explicit), have exactly the same type:
val swap : 'a * 'b -> 'b * 'a val swape : 'a * 'b -> 'b * 'a

Note that F# did not assume that a and b were of the same type. It was quite permissive, attempting to make the function as generic as possible, imposing no particular constraints on the types. Contrast this to the following function:
let f a b = a + b \\val f : int -> int -> int

In this case, F# does not generalize the function it can't, since operator (+) works over numerics and strings, but doesn't work "in general" with other types. F# must bind the parameters to some type, and in this case it chooses int. I do not know the algorithm F# uses to choose this binding. I can only assume it uses the "most natural" one, perhaps defaulting to int for numeric operatons. When you call a generic function, e.g., swap, with typed parameters, the compiler substitutes the function's generic types with those of the passed-in parameters. Understanding this, you can make a function generic, but limit the parameters to being of the same type. In the following example, we add another function to the swap family. We'll call this swapi, since we're forcing the types passed in to be identical.
let swapi(x:'a, y:'a) = (y, x)

Whereas we can call the original swap function with parameters of different concrete types, we can call swapi only with parameters of the same type (indicated in the definition by 'a). We can see this in the following example:
let r1 = swap("hello", 10) let r2 = swapi("hello", 10) let r3 = swapi("hello", "goodbye") \\ok \\error: string expected, got int \\ok

Note that we've only covered generics insofar as they related to F# functions. As we proceed through the book, we'll discover types, etc. that can also be made generic.

Limitations of Generic Functions


In a generic type or function definition, you can use only those members (properties, methods, etc.) that are known to be available on the type parameter. This is required to check function and method calls at compile time. You can apply a constraint to a generic type parameter to notify the compiler that certain methods and functions are available. We will see uses of this later, when we discuss more object-oriented types such as classes. It is possible to write generic code that compiles but still throws an exception at runtime. Here is a simple example:
let max a b = if a > b then a else b val max : 'a -> 'a -> 'a

This function,max, compiles fine, and will run, so long as the elements passed in are of the same type and implement .NET's IComparable interface. Let's look at a few calls:
let let let let r1 r2 r3 r4 = = = = max max max max 10 20 10.0 20.0 10.0 20 "hello" "dolly" \\ok \\ok \\error: mismatched types \\ok, since string implements IComparable

Since all of the types we've studies so far implement IComparable, we need to come up with a custom types that doesn't, so that we can demonstrate writing generic code that compiles yet still fails. Don't worry if you don't understand the class syntax or its use yet we'll get there:
type MyClass1(x: int, y: int) = do printfn "%d %d" x y new() = MyClass1(0, 0) let mc1 = new MyClass1(10,20) let mc2 = new MyClass1(10,30) let r5 = max mc1 mc2 \\error, throws exception since MyClass1 does not implement IComparable

What You Need to Know


Generics provide a powerful and elegant mechanism for defining functions, and other data structures (that we'll study) that can accept a wide variety of types. Generics promote and support data structure and algorithm reuse. F# uses an apostrophe in front of an identifier to indicate a generic type, e.g., 'a or 'b. Automatic generalization describes F# ability to automatically make generic function parameters based on program context. Given F#'s automatic generalization, the need for our explicitly defining generic functions is reduced compared to many other languages. Automatic generalization applies to types (classes) as well as function. You can override F#'s automatic generalization using explicit type definitions either by using concrete types, or by

explicitly limiting the breadth of the generics via type constraints. Even though generic code may compile, it doesn't mean that it will execute successfully at runtime. The generic types and the operations performed on those types must be consistent and compatible; otherwise, your program will throw an exception.

Chapter 10 Lists & Sequences


Introduction
Lists and sequences are powerful collection types that are the workhorses of F# development. In this chapter, we will look at lists and sequences, study the breadth of their functionality, and see how they can be best applied.

Lists
An F# list, defined in Microsoft.FSharp.Collections.List (http://research.microsoft.com/enus/um/cambridge/projects/fsharp/manual/fsharp.core/Microsoft.FSharp.Collections.List.html) , is a set of "things" that exhibits the following characteristics: A list is ordered. A list is immutable both the list itself and the items in the list. All the elements of a list are of the same type. Under the covers, F# implements a list via as a singly linked list that consists of data nodes allocated in a chain, where the first node (the head) contains some data and may refer to a "next" or downstream node. We make a distinction between the first node in the list (the head) and the "rest of the list", collective referred to as "the tail." A linked list is a recursive data structure that terminates when the last node in the chain points to a sentinel value such as null or, in F#'s case, the empty list [](see below). Before we can use a list, we need to create one, so let's get to it.

Creating Lists
The very simplest list you can create or use is the empty list, represented by empty square brackets:
let emptyList = [] \\the empty list, head = tail = [] \\by itself, the empty list is of type 'T \\once it contains an element, the list is of a fixed type

To create a list that initially contains some elements, you can enumerate the individual elements explicitly separated by semicolons, as shown here:
let fruit = ["apple"; "banana"; "orange"] \\list with 3 string elements (head = apple, tail = orange)

Note that the elements of a list appear between square braces and are separated by a semicolon (not a comma[1]), and they must all be of the same type, otherwise, F# will emit a compiler error, as in the following example:
let stuff = ["apple"; 100] \\error, 100 is not a string

The more common and pragmatic way to construct lists is to use list comprehensions.

List Comprehensions
List comprehensions are a succinct, powerful way to construct new lists. F# has two forms of list comprehension syntax: ranges and generators.

Ranges
Ranges take the following form:
[first_element..step..last_element]

Where the first_element is the first element in the list, step, which is optional, is the "count by" parameter, and the last_element is the final value. The first_element and last_element are inclusive, meaning they both appear in the list that F# constructs. Let's take a look at a few examples:
let let let let alphabet = ["'A'".."'Z'"] digits = [0..9] evens = [0..2..20] mul3 = [3..3..99]

To count down, e.g., from 10 to 0, you need to specify a negative step, as in the following example:

let countdown = [10..-1..0]

\\blastoff!

Generators
Generators are another form of list comprehension used extensively in functional programming. List comprehensions that use generators take the following form:
[for <identifier> in collection -> expr] or [for <identifier> in collection do ... yield expr][2]

We will use both forms of list comprehensions in this text. Let break down each one in turn. The first form of list comprehension uses a lambda function to generate the list elements. In the following example, we create a list comprehension that generates the squares of the numbers from 1-10:
let squares = [for i in 1..10 -> i * i] \\squares of 1-10

As you can see here, the square of every element from 1-10 is generated correctly. Suppose, however, we only want the squares of the even numbers from 1-10. The syntax provided in this form of the generator is insufficient to support selective element generation. This is where the second form of list comprehension comes into play.
let evensq = [for i in 1..10 do if i % 2 = 0 then yield i * i] \\even squares

Of course, if it suits you, you can always use the doyield form of the list comprehension, sans the filtering expression:
let squares = [for i in 1..10 do yield i * i] \\we can always use this form

It is also possible for a list comprehension to generate multiple dimensions, using two or more for loops:
let pairs = [for a in 1..3 do for b in 2..5 do yield (a, b)]

yield and yield!


With list comprehensions, we first encounter the keyword yield. The keyword yield is used to generate a single element each time it is called. We saw examples of this above. There is another form of yield, denoted yield! (pronounced yield bang) that is used to generate a collection of elements in the form of a list or sequence. Here is a simple example:
[for a in 1 .. 5 do yield! [ a .. a + 3 ] ] val it : int list = [1; 2; 3; 4; 2; 3; 4; 5; 3; 4; 5; 6; 4; 5; 6; 7; 5; 6; 7; 8]

This list comprehension loops over the integers from 1-5, and for each integer the yield! expression will generate a collection of elements. When you're working with arrays, lists, and sequences, you will sometimes use the yield! expression.

More on List Construction


We've looked at constructing an empty list, creating lists explicitly, and using list comprehensions to generate the lists' elements. There are still several other ways we create lists: using the cons operator (::), concatenating two lists together using the list concatenation operator (@) and using recursion.

cons (::)
To add a new element to the head of a list, we use the right-associative cons operator ( ::). The list we start with may be empty or non-empty. Let's take a look at an example:
let let let let let basket0 basket1 basket2 basket3 basket4 = = = = = [] "fruit" :: [] "banana" :: basket1 "orange" :: basket2 "apples" :: "peaches" :: "pears" :: []

It may be obvious to the careful reader that creating a list explicitly, e.g., ["apple"; "banana"; "orange"], is a shorthand for the cons operator equivalent "apple" :: "banana" :: "pears"::[]. The cons operator is often used in recursive algorithms to build up a resulting list based on some computation. Note that the cons operator does not impact an existing list lists are immutable. The cons operator returns a new list.

concat (@)
You can also build a new list from two or more existing lists via using the @ operator to concatenate them together. Given the

definitions above, we can concatenate lists together like this:


let bigbasket = basket2 @ basket4 \\["banana";"fruit";"apples";"peaches";"pears"] let holiday = basket3 @ basket4 @ ["wine"; "figs"; "fruit cake (yuk!)"]

Creating Lists using Recursion


In F#, we sometimes need to build a list programmatically. Let's suppose, for example, we want to convert an array of integers to a list of integers. Although this is a contrived example, it demonstrates the idea:
let rec arrayToList (a: int array) n = if (n = a.Length) then [] else a.[n] :: arrayToList a (n + 1) let a = Array.create 3 5 let newlist = arrayToList a 0

A question for the reader. Is this implementation tail recursive? [3] Happily, the F# List and Array modules supply generic to_array and to_list functions respectively, so we don't need to write our own like we've done here. Note that we will see other ways to recursively build lists when we study pattern matching.

Using Lists
Now that we know how to create lists, we need to understand how best to use them. In this next section, we'll cover some of the more interesting and useful List functions. Since we have covered many of the functional concepts, e.g. folding and filtering, when we discussed functions (Chapter 8), we won't rehash them here. In addition, since we now know how to read generic type signatures, we'll be able to understand the documentation for the List functions in all their majesty (OK, that's a bit much).

Initialization
Yet another way to initialize a list is to use the List.init function. This function uses a lambda to initialize the list's elements:
let lst = List.init 10 (fun n -> 100 * n) \\10 elements: 0-900 by 100s let lst2 = List.init 5 (fun n -> "hello" + string n) \\5 elements: hello0-4

Checking for the Existence of Elements


Many times it's necessary to check to see if a list contains elements or has a positive length. List.isEmpty and List.Length help us out here:
let empty = List.isEmpty(lst) let len = lst2.Length

You may also want to test to see of the list contains at least one element that meets the criteria of a given predicate:
let doesExist = List.exists(fun elem -> elem > 500) lst

You can also write test to check if all elements of the given list satisfy the given predicate:
let allEven = List.forall(fun elem -> elem % 2 = 0) lst

Accessing Elements
Because we generally process lists recursively, there are two functions that we use often. List.hd retrieves the first element in the list, while List.tl retrieves everything but the head:
let squares = List.init 5 (fun n -> n * n) let head = List.hd(squares) let tail = List.tl(squares) val squares : int list = [0; 1; 4; 9; 16] val head : int = 0 val tail : int list = [1; 4; 9; 16]

\\could also use squares.Head \\could also use squares.Tail

There is another function nth that retrieves the nth element from the list. The nth function makes the list look like an array from the perspective of element retrieval. The lists head is considered to be at index 0.
let cubes = List.init 5 (fun n -> n * n * n) let eight = List.nth cubes 2 val cubes : int list = [0; 1; 8; 27; 64] val eight : int = 8

Finding and Filtering


You can find elements in a list by using predicates or by index. In the following example, we use List.find to find the first element for which the predicate is true. We then use the List.findIndex function to return the index of the first element that

satisfies the given predicate.


let cubes = List.init 5 (fun n -> n * n * n) let results = List.find(fun n -> n > 0 && n % 9 = 0) cubes val results : int = 27

As we saw when we studied arrays, filtering is a common operation on collections. It should come as no surprise that List offers a filter function as well. This function returns a new collection containing all the elements that satisfy the given predicate.
let kids = ["jessica"; "kimberly"; "melissa"] let youngest = List.filter(fun name -> name >= "k") kids

Sorting
Lists also give us the ability to sort them in various ways. The simplest but least powerful is the sort function. This function uses the natural order of the input arguments, e.g., strings are alphabetized, numbers are sorted lowest to highest, etc.: let planets = ["mars"; "venus"; "mercury"; "earth"] let alphabetical = List.sort planets

If you need to take control over the sorting, you can use List.sortWith, which enables you to supply your own lamdba function. F# hands the lambda a pair of elements at a time (think of them as the left operand and the right operand) and the lambda returns either -1, 0 or 1 (-1 = left is smaller, 0 = both equal, 1 = right is smaller). In the following example, we build a list of tuples. Each tuple contains the name of a planet, and it's ordinal order from the sun (Mercury is the closest, followed by Venus, etc.) Our lambda function extracts the second element from each tuple (using F#'s snd function) and uses them as the basis of the sort.
let planets = [("mars", 4); ("venus", 2); ("mercury", 1); ("earth", 3)] let distanceFromSun = List.sortWith(fun x y -> if (snd x) < (snd y) then -1 else 1) planets

Note that quite often, we'll use the pipeline operator to feed input into List's functions. We could have written the previous example as follows:
let planets = [("mars", 4); ("venus", 2); ("mercury", 1); ("earth", 3)] let distanceFromSun = planets |> List.sortWith(fun x y -> if (snd x) < (snd y) then -1 else 1)

Using Aggregate Operators


The List module also provides a family of aggregate functions. These functions are quite powerful, and enable you to implement sophisticated processing engines. Note that we saw many of these functions when we discussed arrays. Let's take a look at them again from the perspective of the List module.

Iteration
The List.iter family of functions iterates through each element in the list, calling a function for each element visited. Note that the List.iter functions do not return a value - they simply enable you to visit each element. The function that's executed per element must return unit.
let blastoff = [10..-1..0] blastoff |> List.iter(printfn "%d")

The other functions in the family include List.iter2, List.iteri, and List.iteri2. Let's look at an example that uses 2 lists. The lists need to be the same size or F# will throw an exception.
let continents = ["n.america"; "s.america"; "europe"; "asia"; "africa"; "australia"; "antarctica"] let population = [524000000L; 382000000L; 731000000L; 4000000000L; 922000000L; 21000000L; 1000L] List.iter2(fun c p -> printfn "%s has population %d" c p) continents population

Mapping
Recall that mapping is the process of transforming one set of elements, the source, into another set of elements, the target. When F# executes List.map, it visits each element in the source and passes it to a (lambda) transformation function that we supply. In the following example, we convert a list of integers representing the ordinal order of planets into their corresponding names. Note that this is a very contrived example; however, I want to demonstrate that you can do much more than square numbers:
let planets = [("mars", 4); ("venus", 2); ("mercury", 1); ("earth", 3)] let planetOrds = [1; 2; 3; 4] let names =

planetOrds |> List.map (fun po -> fst(List.find(fun p -> snd p = po) planets))

The first two lines are simple enough. They create the lists that we'll use as the basis of our mapping. The next line (which extends over 3 physical lines) runs the List.map function over the planetOrds list. We can see that planetOrds is piped (|>) into List.map as a parameter. For each ordinal fed into List.map, F# executes the supplied lambda function. This lambda function interrogates the planets list, looking for a tuple whose second (snd) element equals that of the current ordinal. When it finds the correct tuple, it returns the first (fst) element of that tuple, which is the planet's name. The target names array thus contains the list of planet names in ordinal order from the sun.

Folding
As discussed previously, functional languages use folding and unfolding to process collections. Folding (closely related to reducing) is the process of distilling a list to a single value, where unfolding is the process of generating a collection. The List module supports a family of fold methods, many of which we've seen already. The two primary methods in this family are fold (for folding left) and foldBack (for folding right). We present a few examples here for completeness.
\\sum numbers 1-10 using a left fold let accumulate acc x = acc + x let sum = List.fold accumulate 0 [1..10]

\\function to run (folding function) \\folding func, init accumulator, list

Note that in many examples of folding that you will see, the accumulator function, e.g., accumulate in the previous example, will be a mathematical operator listed in parentheses. For example, the add operator looks like this: ( + ) and the multiplication operator like this ( * ). We will cover operators and operator overloading later. For now, it's sufficient for you to understand that these operators are (surprise, surprise) just more functions. They expect 2 parameters, e.g., a + b or x * y. To bring this idea home, the following example demonstrates computing a factorial using List.fold and the mathematical operator ( * ) as the accumulator function:
let factorial n = [ 1 .. n ] |> List.fold ( * ) 1 \\For each integer 1..n, the accumulator = accumulator * n. \\The accumulator starts off at 1. let result = factorial 5 \\result = 120

The foldBack function enables us to perform right folds (we process the input list from right to left vs. left to right). Note that folding a list left vs. folding it right can yield different results depending on the operator applied, i.e., folding is not commutative.
let nums = [0..4] let diff = List.foldBack(fun element acc -> acc - element) nums 0 \\diff = 0 - 4 - 3 - 2 - 1 - 0 = -10

Recall that is you need access to the intermedia value of the folding operation, you can use List.scan and List.scanBack, as demonstated in Chapter 8.

Converting Lists
There are times when you're working with a List, but need to turn it into a different data structure. This occurs often when you need to convert a list to an array or a sequence to take advantage of some functionality the other data structure offers, e.g., when you're using a library that needs an array as input, or that you need the rich semantics of a sequence. The List module has two convenience functions for converting to arrays and sequences.
List.to_array builds an array from the List.to_seq builds a new sequence.

given collection.

Calling these functions is trivial:


let nums = [0..4] let a = List.to_array nums let s = List.to_seq nums

Sequences
Sequences, defined in the Microsoft.FSharp.Collections.Seq (http://msdn.microsoft.com/en-us/library/ee353635(VS.100).aspx) module, are conceptually similar to lists. Both data structures are used to represent an ordered collection of values all of homogenous type. However, unlike lists, elements in a sequence are computed lazily as they are needed, rather than computed all at once. This gives sequences some interesting properties, such as the ability to represent infinite data structures. A sequence is fundamentally an enumerable data structure that maps to System.Collections.Generic.IEnumerable<T> (http://msdn.microsoft.com/en-us/library/9eekhta0.aspx) under the covers. The bottom line is that when you create a sequence, you are creating an IEnumerable.

Creating Sequences
When we talk about creating sequences, we generally talk about "generating sequences", since the elements are produced on-

demand, a.k.a., generated. Sequences are defined using the following syntax:
seq { expression }

The expression is often referred to as a sequence expression. Similar to lists, sequences can be created using range expressions of various types, e.g., integers, floats, etc.
let s = {1..10} let fs = {1.0..2.0..8.0} \\val it : seq<int> = seq [1; 2; 3; 4; ...] \\val it : seq<float> = seq [1.0; 3.0; 5.0; 7.0]

Because sequences are evaluated in a lazy manner, you can create very large sequences with almost zero penalty. When you create a large sequence (or any sequence for that matter), what you are really doing is setting up a collection that can be potentially generated. For example, to create a sequence with 10 million integers, we we can write the following:
let bs = {1L..1000000L}

This "big sequence" is no more expensive to create than the the first two in the previous example. The sequence elements are only generated when needed. Sequence expressions may involve for, if and let expressions. These types of sequence expressions are akin to the list comprehensions discussed earlier. The general pattern for a sequence expression is:
seq { for value in expr .. expr -> expr } or seq { for value in expr do .. yield expr } or set { for pattern in seq -> expr }

Let's look at some examples to illustrate the idea. You should already be familiar with the first two styles based on list comprehensions:
let s1 = seq { for i in 0..10 -> (i, i + i) } let s2 = seq { for i in 0..10 do yield (i, i * i) } let s3 = seq { for i in 0..10 do if i % 3 = 0 then yield i }

Using a let expression in a sequence expression enables you to compute intermediary results. A common example is shown below:
let processInfo = seq { for p in System.Diagnostics.Process.GetProcesses() do let name = p.ProcessName let threadcount = p.Threads.Count yield (name, threadcount) }

The examples above all used the yield keyword to return a single result. As with lists, you can use the yield! (yield bang)[4] keyword to return another sequence vs. a single element. The following examples demonstrates the use of yield! in sequence expressions[5]:
let rec allFiles dir = seq { for file in Directory.GetFiles(dir) -> file for subdir in Directory.GetDirectories dir do yield! (allFiles subdir) }

In addition to the use of yield! we see here another common sequence pattern that of using a secondary iteration (another for loop). F# deals with multiple interations in sequences expressions by generating secondary sequences and concatenating the results to the previous ones. The last form of sequence expression uses a pattern. A pattern, which we will cover in detail in Chapter 11, is an input with a known structure. Pattern matching is the act of checking to see if the structure of the given pattern matches a set of rules. F# understands patterns and can carry out pattern matching in a variety of contexts. For our immediate purposes, let's take a look at a sequence expression that leverages patterns:
let tups = [(1,2); (3,4); (5,6); (7,8)] let revtups = seq { for (a, b) in tups -> (b, a)}

(a, b)

Here, tups is a list of tuples. Each tuple in this list has the structure (x, y). In the next line, we ask F# to match up the structure with the structure (x,y), e.g., (1,2) would match and set a=1 and b=2, the values from the tups element. If the patterns match, as they do here, F# assigns the first element, a, to the first element of the tuple, and the second element, b, to the second element of the tuple. It then yields (->) a new tuple which contains the values in reverse order. The output from the F# Interactive Console is:
val tups : (int * int) list = [(1, 2); (3, 4); (5, 6); (7, 8)]

val revtups : seq<int * int>

Because revtups is a sequence, the values aren't generated yet they simply can be generated. Let's force F# to generate the elements of the sequence and output them to the F# Interactive Console:
> revtups;; val it : seq<int * int> = seq [(2, 1); (4, 3); (6, 5); (8, 7)]

Note that sequences are compatible with List, Array or [], and the other .NET collection types such as
System.Collections.Generic.SortedList<T>.

Using Sequences
Like arrays and lists, sequences support iteration, aggregate operations such as folding, mapping, etc. The functions , e.g., Seq.map, defined in the Seqe module are exact parallels to those defined in the List and Array modules; therefore, it doesn't make a lot of sense to rehash them here. Instead, let's examine some of the new and different functions specific to sequences themselves. Of course, the functions we discuss here are not exhaustive, but representative of the more commonly used ones. As with any module, please consult the documentation for full details[6]. is a function that creates a sequence from a function that itself return a sequence. Why on earth would you need that, since standard sequences are already delay computed? The answer is rooted in the fact that the creation of certain sequences can cause side effects and you may want to delay those side effects. Side effects are prevelant, for example, when you interact with the .NET libraries. Let's take a common example of iterating over the directories and files in a given directory, which we discussed previously:
Seq.delay let rec allFiles dir = seq { for file in Directory.GetFiles(dir) -> file for subdir in Directory.GetDirectories dir do yield! (allFiles subdir) let sysfiles = allFiles @"C:\windows\system32"

In this example, the creation of the sequence causes F# to generate the first set of files from the root directory dir passed into the function. From Don Syme's Expert F#:

One subtlety with programming with sequences is that side effects such as reading and writing from an external store should not in general happen until the sequence value is actually iterated. In particular, the allFiles function as specified above reads the top-level directory C:\ as soon as allFiles is applied to its argument. This may not be appropriate if the contents of C:\ are changing. You should delay the implementation of the sequence until iteration is performed. That is, when data sources may change and you wish to see the changes in subsequent iterations then a sequence value should be a "specification" of a how to generate a sequence rather than a single read of the data source. You can achieve this by using Seq.delay, shown below.
let rec allFiles dir = Seq.delay (fun () -> let files = Directory.GetFiles(dir) let subdirs = Directory.GetDirectories(dir) Seq.append files (subdirs |> Seq.map allFiles |> Seq.concat))

So, the moral of the story is: when you are interacting with external data sources that can change out from under you, and you want to make sure that you get the latest-and-greatest data from these sources via sequences, consider using Seq.delay. To provide a bit more insight into what the compiler generates, we can use Reflector to get a better sense of what's happening (C# syntax as produced by Reflector). Here is what the non-delayed function looks like:
public static IEnumerable<string> allFiles(string dir) { return new allFiles@8(dir, null, null, null, null, null, null, 0, null); }

Here is the delayed version:


public static IEnumerable<string> allFilesDelayed(string dir) { return SeqModule.delay<string>(new allFilesDelayed@12(dir)); }

As you can see, the non-delayed version constructs the IEnumerable immediately, where the delayed version waits to construct the IEnumerable. If the construction of the IEnumerable produces unwanted side effects, you have Seq.delay at your disposal. One of the functions that we did not cover when discussing Arrays or Lists is concat (used in Don Syme's example above). While not the exclusive domain of the Seq module, you will see it used with sequences somewhat often. With a name like concat, it's probably not too surprising that it concatenates its inputs together. It is often used in conjunction with recursive functions and data structures for building up a result. concat takes a list of enumerables and returns a single enumerable. Most of the examples

on this topic are somewhat arcane, so to be clear we'll create a simple, albeit contrived, example to demonstrate the idea. For this example, it's easiest to build a data structure that explicitly contains a collection of enumerables. We will tap into the .NET libraries for help[7].
\\Build up a list of string[]. This is our "sequence of sequences". open System.Collections.Generic let words = let wordList = new List<string[]>() wordList.Add([| "mary"; "had"; "a"; "little"; "lamb" |]) wordList.Add([| "it's"; "fleece"; "was"; "white"; "as"; "snow..." |]) wordList \\Tell F# to take the sequences and string them together. Take the final \\sequences and run it through Seq.iter to dump all the words. let rhyme = words |> Seq.concat |> Seq.iter(fun w -> printf "%s " w)

Note that Seq.concat differs from a similarly named function Seq.append, the names of which can be confusing. Whereas concat "strings together" a set of enumerables into a single enumerable, append takes two sequences and adds one to the end of the other. The function signatures tell the story:
let let val val concat_sig append_sig concat_sig append_sig = = : : Seq.concat Seq.append (seq<#seq<'b>> -> seq<'b>) (seq<'a> -> seq<'a> -> seq<'a>)

What these signatures tell us is that concat is a function that takes a sequence set and returns a sequence that is type compatible with the set. The #seq notation has to do with flexible types, which we'll cover later. The signature for append, on the other hand, tells us that this function takes 2 different sequences and returns a new sequence.

Converting Sequences
When working with sequences, it's often convenient to turn them into arrays and lists. To convert a sequence into an array, use the Seq.to_array function, as shown here:
let arr = seq { 1..10 } |> Seq.to_array

You have the same option to turn the sequence into a list as well using Seq.to_list:
let lst = seq {1..10} |> Seq.to_list

Well, you know now enough about lists and sequences to understand many of the samples that you will encounter in the wild. You also have enough background to make some sense of the F# documentation, and can probably write some non-trivial F# code. Let's use this momentum and dive into pattern matching.

What You Need to Know


Lists are immutable data structures that hold an ordered set of elements, all of the same type. Under the covers, Lists are implemented as singly linked lists. Lists, like most data structures in functional programming, are generally processed recursively. Lists have a wide range of built-in operations including folding, mapping, zipping, etc. You should already have enough F# knowledge now to understand th documentation for Lists. Lists can be constructed using the cons (::) operator, the concatenation ( @) operator, using explicit delineation of elements, or via list comprehensions. During iteration/comprehension, yield returns a single element, while yield! (yield bang) return a collection of elements. Sequences are enumerable data structures whose elements are evaluated lazily (on demand). In other words, they are F#'s way to create and use IEnumerable<T>. You create sequences using the seq { } syntax and a sequence expression. The expression can list the elements explicitly, use a compatible collection such as a list, or use an arbitrary function to generate the elements. Like lists and arrays, sequences support a full complement of functions including mapping, unfolding, and (unique to sequences) infinite constructs.
Using commas is a common mistake, and results in type-related error messages. You may see older F# examples that use a when guard in list comprehension. As of this writing (Sep 2009), the when guard is deprecated. Use doyield instead. [3] No, since the cons operator is outstanding. To convert this to a tail recursive function, we need an "accumulator". [4] In some texts and samples, you might see yield! replaced with the ->> operator. As of this writing, the ->> operator is deprecated. Use yield! instead. [5] This sample taken from Expert F#, by Don Syme. [6] One of my goals with this text is to enable you to read and understand the F# documentation at a fairly deep level. [7] This sample was adapted from a similar example in Foundations of F# by Robert Pickering.
[1] [2]

Chapter 11 Aggregate Types


Introduction
When we program in strongly typed languages, we often find it is necessary to work with data types that capture the semantics of our domain, e.g., when writing accounting software, we could model solutions in terms of debits, credits, etc. Using domain semantics helps us to keep our solutions transparent, simpler to understand, and more natural to work with. As a multi-paradigm language, F# supports structured types, e.g., discriminated unions, as well sophisticated objects that support full OO functionality. In this chapter, we study F#'s built-in structured types and learn how to define our own. To begin, let's look at how we can access existing types via type abbreviations,

Type Abbreviations
The simplest way to get started with types is to discuss type abbreviations, which are alternate names or aliases for existing types[1]. We use type abbreviations to give existing types meaningful names, in order to make code clearer and easier to read. We also use them to create short names for types that are otherwise unwieldy to work with. Additionally, we use type abbreviations to make it easier to replace a type without changing all the code that uses that type. In the following code snippet, we define several type abbreviations:
type type type type arrIndex = int temperature = double point = float * float student = string * float * bool

These type abbreviations are fundamentally aliases, e.g., arrIndex for int and point for float * float. Since the type names help indicate what the types are used for, you can see how type abbreviations can help clarify intent. Once defined, you can use abbreviated types anywhere you'd use the orignal type. For example, given the type abbreviations defined above, we can write the following;
let student joe = ("joe", 3.2, true) or let joe: student = (" joe ", 3.2, true)

By convention, type abbreviations are lowercase, but this is not a technical requirement or constraint. Back in Chapter 9, we discussed generic functions, and how F# enabled us to specify generic function arguments. The idea of generic arguments extends to type abbreviations. For example, let suppose we want to create a new abbreviated type based on .NET's built-in generic collection class System.Collection.Generic.Dictionary (http://msdn.microsoft.com/en-us/library/xfhwa508.aspx) . We can do this by creating a type abbreviation that accepts a generic argument. The generic argument appears in angle brackets as part of the abbreviation's definition. In the following code snippet we define a type that represents an associative array that uses string-based keys to hold generic values:
type AssocArray<'a> = System.Collections.Generic.Dictionary<string, 'a>

Now, when we create an AssocArray, F# will ensure that we supply a type parameter, which will be used to instantiate a new System.Collections.Generic.Dictionary that uses stores whatever type we specify, and uses strings as its lookup keys, e.g.:
let mylist = new AssocArray<int>()

Using type abbreviations, we can alias any type, including arrays, function types, tuples, etc. The following example illustrates a type abbreviation that aliases functional types:
type Transformer<'a, 'b, 'c> = ('a -> 'b) -> ('b -> 'c)

Type abbreviations are nothing more than aliases. During F#'s compilation process, they are expanded into the standard type format shared by all .NET languages.

Enumerations
While type abbreviations enable us to alias existing types, enumerations give us a way to create our own types. Enumerations have a defined set of named values. You can use them in place of literals to make code more readable and maintainable. They take the following general form:
type enum-name =

| | | |

value1 = literal1 value2 = literal2 ... valueN = literalN

The literals can have the type sbyte, byte, int16, uint16, int32 (the default), uint32, int64, uint64 and char. Enumerations in F# are mapped to the.NET Enum (http://msdn.microsoft.com/en-us/library/system.enum(VS.100).aspx) class, which is a value type, meaning they are allocated on the stack and use pass-by-value semantics. In the following example, we define a simple enumerated type to represent a Web protocol:
type Protocol = | FTP = 0 | HTTP = 1

Those coming from the C-family of languages beware. If you omit the literals, you no longer have an enumeration, but a discriminated union (discussed later in this chapter). You can also compact the representation of enumerations by placing them on the same line:
type Color = | Red = 0 | Green = 1 | Blue = 2

It is simple to convert an enumeration to its underlying, corresponding value by using the appropriate casting operator:
type Color = | Red = 0 | Green = 1 | Blue = 2 let c = Color.Blue let n = int c \\cast c to corresonding int value

Whenever you access an enumerated vaue, F# requires that you use the enumerator's full name, e.g., you must use Color.Red, not just Red by itself. To change the default type of an enumeration from int32 (the default) to something else, you need to specify the type of each element, as shown here:
type Days = | Sunday = 0x1uy | Monday = 0x2uy | Tuesday = 0x4uy | Wednesday = 0x8uy | Thursday = 0x10uy | Friday = 0x20uy | Saturday = 0x40uy

This example uses unsigned bytes (uy) to represent the various days of the week. You can use the enum function in the F# library to generate an enumeration value, even a value other than one of the predefined, named values. For example, given this Color enum:
type Color = | Red = 0 | Green = 1 | Blue = 2

You use the enum function to programmatically create an additional entry:


let purple = enum<Color>(3)

We can also use enumerations in conjunction with pattern matching, as demonstrated in the following example:
let isPrimary color = match color with | Color.Red | Color.Green | Color.Blue -> true | _ -> false

Records
The next rung in the type sophistication ladder of is that of records. A record represents a simple aggregate of named values that enable us to build data structures that contain named fields. The general form of a record type is:
type [accessibility-modifier] typename = { [ mutable ] label1 : type1; [ mutable ] label2 : type2; ... }

In the following example, we define a record that contains information about a movie:
type Movie = { Title: string; ReleaseYear: int; }

Each record element consists of a named field and data type, separated by a colon, e.g., Title: string. Each record element is separated by a semicolon. Once you've defined a record type, you can construct instances of the record using using the let keyword, as shown here:
let funnyMovie = { Title="Pineapple Express"; ReleaseYear=2008 }

When you create an instance of a record, you need to initialize every field. Forgetting to initialize a field results in a compiler error. Constructing a record instance looks similar to defining a record. It helps to keep in mind that when you define a record type, you use the keyword type and delineate the record's fields and data types. In contrast, when constructuing a record instance, you use the keyword let and assign values (via =) to each of the record's fields. You use the brackets { } in both cases. Record fields are not limited to simple types. You can use lists, arrays, etc. as part of a record's definition. To demonstrate this, let's define a new Movie record that includes the list of star actors:
type Movie = { Title : string; ReleaseYear: int; Actors : string[]; } let funnyMovie = { Title="Pineapple Express"; ReleaseYear=2008; Actors=[|"Seth Rogen"; "James Franco"|] }

By default, like all values in F#, record elements are read-only. If you wish to make record elements writeable, use the mutable keyword, as shown here:
type Employee = { Name : string mutable Salary : float }

\\semicolon optional when elements \\on a separate line

let joe = { Name="Joe Smith"; Salary = 50000.0 } joe.Salary <- joe.Salary * 1.1 \\Give Joe 10% raise

Note that if an element is inherently mutable, as is the Actors field defined in the Movie type above (by virtue of the fact that it is an array, and arrays are inherently mutable), you can change its contents without using the mutable keyword. What you cannot do is change the referenced element. In other words, given the Movie type as defined, you can update or change the contents of the existing Actors array, but you cannot replace the array with a new array. In code:
funnyMovie.Actors.[0] <- "Ed Helms" funnyMovie.Actors <- [| "Zach Galifianakis" |] \\works \\error, Actors is not mutable

If you define two or more record types and find that these types contain identical element names, you will need to disambiguate them during instance construction. For example, given an Employee class and an Actor class, both with elements Name and Salary, you need to tell F# which record you're trying to construct; otherwise, F# will choose the most recently defined one. You disambiguate using the record type name followed by a dot ( . ). Let's look at an example:
type Employee = { Name : string; mutable Salary : float; } type Actor = { Name : string; mutable Salary : float; } let x = { Name="Joe Smith"; Salary=50000.0 } let y = { Employee.Name = "Mary Brown"; Salary=60000.0 } \\Actor, since most recently defined \\Employee, explicit

Copying Records
In addition to the mechanisms we've discussed so far, we can also construct records via cloning. For example, given a record of

type Employee, we can easily create an Employee record and copy it using the with keyword. In the process of making the copy, we can replace whatever element values we'd like, so that the newly constructed copy assumes the new values:
type Employee Name Salary HireYear } = : : : { string; float; int;

let joe = { Name="Joe Smith "; Salary=65000.0; HireYear=2001 } let mary = { joe with Name="Mary Jones"; Salary=75000.0 } \\copy joe replacing name and salary

Augmenting Records with Operators


Although we've already introduced operator overloading, we did so only from the perspective of introducing them in the global namespace. Now that we've discussed record types, we're in a position to revisit operator overloading in a new context. To overload an operator to be used with specific record types, we use the following syntax:
static member (operator-symbols) (parameter-list) = method-body

Here, we see a new keyword static, which means that the member becomes part of the record type itself vs. instances of the type. We'll discuss static in detail when we cover classes. The member keyword is also new, and tells us that the operator is a "member of"/"part of" the public interface of the record type. The rest of the operator definition remains unchanged vis--vis a standard operator as introduced previously. In the following example, we define a record type called PolarCoord that represents a point in polar coordinates. As part of the record type, we define an operator +that enables us to easily add PolarCoords together. Since we're defining the operator + to be applicable only to PolarCoords, we do not risk muddying the global namespace, nor do we overload the standard plus (+) operator.
open System type PolarCoord { r : double angle : double } static member ( + ) (c1 : PolarCoord, c2 : PolarCoord) = \\Need to convert to rectangular coords, add, then convert back let (x1, y1) = (c1.r * Math.Cos(c1.angle), c1.r * Math.Sin(c1.angle)) let (x2, y2) = (c2.r * Math.Cos(c2.angle), c2.r * Math.Sin(c2.angle)) let (x3, y3) = (x1 + x2, y1 + y2) let r3 = Math.Sqrt(x3 * x3 + y3 * y3); \\We need to define "r3" here, since the "r" defined in \\the record (below) is not visible to the rest of the \\record, and therefore, cannot be used in the match expression. \\Go figure. \\Build the resultant PolarCoord { r = r3 angle = match (x3, y3) with | (0.0, 0.0) -> 0.0 | (x3, _) when x3 >= 0.0 -> Math.Asin(y3 / r3) | (x3, _) when x3 < 0.0 -> -Math.Asin(y3 / r3) + Math.PI } let p1 = { r = 1.0; angle = 10.0 } let p2 = { r = 5.0; angle = 72.5 } let p3 = p1 + p2

When overloading operators in record types, whitespace is critically important. The braces that define the record must be aligned, and the static keyword must vertically align with the closing brace.

Discriminated Unions
The next type in our F# bag of tricks is the discriminated union, an important and often-used construct in F# programs. A discriminated union (DU) is a data type with a finite number of distinct, alternative representations. I think that it's helpful to think of a DU as a polymorphic type akin to a union in traditional C. In functional programming, discriminated unions often are used to replace single-inheritance hierarchies. For example, let's assume that we want to represent a set of simple operating system constructs such as files, processes, and handles. To model this type of system in OO fashion, we'd most likely create an abstract class OSObject and from this derive subclasses such as File, Process, and Handle. We can do something very similar with DUs, as shown in the following example:

type OSObject = | File of string \\name | Process of string * int name and priority

Here, we are declaring a DU called OSObject that contains two discriminators: File of type string, and Process of type string * int, which is a tuple. As you can see, each discriminator can be of a different type. Note that each discriminator must start with an uppercase character. This is somewhat odd due to the fact that F# does not normally restrict case outside of its built-in keywords. To use the OSObject DU, you create instances of the discriminators directly[2]:
let f = File("fsharp.txt") let p = Process("iexplore.exe", 1)

Here we're creating an OSObject of type File. Since File was specified to be of type string, F# generated a compliant constructor and we're invoking it. We also create a Process, that accepts 2 arguments of type string and int respectively. In addition to creating discriminators of explicit type, you can create discriminators that do not specify types explicitly. In the following code, we add Unknown to our OSObject DU:
type OSObject = | File of string | Process of string * int | Unknown

\\name \\tuple (name, priority) \\unknown type

When F# encounters Unknown, it generates a simple class that contains a default constructor, enabling us to create instances, as shown here;
let u = Unknown

DUs enable us to treat the discriminators polymorphically. For example, if we wanted to create a factory method for creating new OS objects (OSObjects), we could do so as follows:
let makeOSObject objtype = if objtype = "file" then File() else if objtype = "process" then Process(, 0) else Unknown()

Because is it an expression, the makeOSObject function must resolve to a single return type. Since all of the potential return types fall under the OSObject umbrella (they are polymorphic with repsect to one another) F# considers a valid return type any OSObject. This enables us to return a File, a Process or an Unknown. To further flesh out DUs, let's look at some examples that could form the basis of a fantasy role-playing game:
type FantasyCharacter = | Warrior | Wizard | Thief type OffensiveWeapon = \\ints represent offensive strength | Sword of int | Mace of int | MagicStaff of int type DefensiveWeapon = \\floats represet defensive strength | Shield of float | ChainMail of float

Once we've defined DUs, we can use them stand-alone or as components of other types. For example, we can define a Player type that consists of a string, a FantasyCharacter and an OffensiveWeapon:
type Player = { Name: string; Character: FantasyCharacter; Offense: OffensiveWeapon; } let conan = { Name="Conan"; Character=Warrior; Offense=Sword(100) }

We can even combine discriminators in tuples, arrays, etc. Here is another example where we create a tuple our of two discriminators:
type Player = { Name: string; \\string Character: FantasyCharacter; \\discriminator Weapons: OffensiveWeapon * DefensiveWeapon \\tuple of discriminators } let conan = { Name="Conan"; Character=Warrior; Weapons=(Sword, Shield) }

Let's look at another example, this time switching gears from fantasy games to books. This example throws in type abbreviations

for good measure:


type Title = string type PubYear = int type Author = string type Book = | NonFiction of Title * Author * PubYear | Fiction of Title let bizbook = NonFiction("Good to Great ", "Jim Collins", 2001) let goodread = Fiction "Shogun"

Note here that we've abbreviated the types Title, PubYear and Author, and defined the NonFiction discriminator as a tuple of them all. As with other types, you can construct arrays and lists of discriminators, as shown here:
let bizlibrary = [ NonFiction("Tipping Point", "Malcom Gladwell", 2000); NonFiction("Made to Stick", "Chip & Dan Heath", 2007); Fiction("The Lost Symbol") ]

Recursive Definitions
A powerful feature of DUs is that they can include recursive references. This enables us to define data structures in a recursive manner. The classic example of a recursive data structure is a tree, and it turns out that in F# we often use DUs to define them. In the following example, we use a DU to define a recursive tree structure whose leaf nodes can contain any data type (as defined by a generic parameter 'a):
type Tree<'a> = | Leaf of 'a | Node of Tree<'a> * Tree<'a>

Given the Tree structure above, we can build a tree as follows:


let t = Node(Node(Leaf(100), Leaf(200)), Leaf(50))

You can also write a function [3] that walks the tree and prints out its values in an easy-to-read style:
let walkTree tree = let rec loop depth tree = let spacer = new string(' ', depth) match tree with | Leaf(value) -> printfn "%s |- %A" spacer value | Node(tree1, tree2) -> printfn "%s |" spacer loop (depth + 1) tree1 loop (depth + 1) tree2 loop 0 tree

Here, again, I'd like to point out the common pattern of using recursion and pattern matching to define concise, elegant processing constructs. A side note on the example: Although we have not covered it yet, the match statement, among its other functions, can be used to distinguish among a given set of discriminators. It's sort of like a an ifelse chain or switch statement in C. We will cover match fully in Chapter 12. F# ships with some built-in discriminated unions that prove quite useful, one of which is the option type[4]. The option type enables our expressions to evaluate to "something" or "nothing" using the discriminators Some and None respectively. In other words, option is used when a value may or may not exist. Here is its definition:
type 'a option = | None | Some of 'a

Options

When using the option type, our expressions use Some to tell the caller that "the result is valid" and None to tell the caller that "I cannot give you an answer." Although we could solve this problem in different ways, using options is a well accepted F# idiom. Let's look at a few examples to help clarify how we use options. In the first example, we will look at a case of classic division, where we divide a numerator by some denominator:
let classicDiv a b = a / b

This is a perfectly valid function, and works properly except when b = 0. If we call this function with b = 0, F# will throw a DivideByZero exception. The caller can certainly catch and deal with the exception, or we can use the option type to assist the caller in understanding the nature of the return value. Here is a safe version of classic division:
let safeDiv a b = if b <> 0 then Some(a / b) else None

Options are used frequently to check database query results, report errors from object contruction, and in other instances where a value might be legitimately null. Until you learn to use pattern matching (in the next chapter) to check the "Some-ness" or "None-ness" of a return value, you can use the Option.isNone and Option.isSome static functions in an if expresson, as shown below:
let safeDiv a b = if b <> 0 then Some(a/b) else None let f = safeDiv 9 3 if Option.isNone(f) then printfn "You can't divide by 0!" else printfn "The answer is %d" f.Value

Notice here that you can pull the intrinsic value from the option type via the Value function. You can accomplish the same thing using Option.get.

Reference (Ref) Cells


Even though F# discourages side effects, there are times, e.g., when interfacing with other .NET languages, that we need to change the state or values, data structures, etc. We can use the mutable keyword, as you've seen; however, mutable values have some limitations, including that you cannot use them outside the scope in which they are declared " for example, we cannot use a mutable value declared externally inside a function. The following code snippet, for example, will not compile.
let counter() = let mutable count = 0 (fun () -> count <- count + 1; count)

This example is trying to define a function counter that returns a function (a closure) with a side effect. The side effect is incrementing the mutable value count but count would then be used outside the scope in which it is declared whenever the function returned from counter is invoked, and this is illegal. The specific feedback we get from the F# compiler is:
The mutable variable 'count' is used in an invalid way. Mutable variables may not be captured by closures. Consider eliminating t his use of mutation or using a heap-allocated mutable reference cell via 'ref' and '!'

To make it simpler and more flexible to deal with mutable state, F# offers the Ref type. The Ref type is a record that wraps mutable contents of arbitrary type. A Ref type is defined as follows:
type Ref<'a> = { mutable contents: 'a }

Values of type Ref are called reference cells. Unlike mutable values, reference cells overcome the limitation of being accessible outside their declaring scope. In addition, F# provides helper functions for working with them. To create reference cells, we use the ref keyword, followed by a reference expression, as shown in the following example:
let daughter = ref "kimberly"

Here, daughter represents a reference cell it "wraps" or "points to" the string kimberly. To change the value referenced by the reference cell, daughter, we use the reference assignment operator :=
daughter := "chee"

Now the value of daughter is chee, and the former value, "kimberly", is forgotten. We access a reference cell's value using the cell dereference operator ( !):
printfn "kim's nickname is %s" !daughter

All in all, a ref type uses pointer-like semantics. It refers to a value and must be dereferenced when used. The value returned by the dereference operator (!) is read-only. To assign a value to a reference cell, use the Value function and the destructive assignment operator (<-), as shown below.
let pi = ref 3.14 pi.Value[5] <- 3.1415926

Somewhat surprisingly, if we create a reference cell that refers to another variable, changes that we make to the reference cell via

:=

do not affect the referenced variable. In the following example, we can see that y references x. When we increment y, x remains unchanged.
let x = let y = y := !y printfn 123 \\x = 123 ref x \\use x as initial value for y + 1 \\see note below "x=%d, y=%d" x !y \\print results (x=123, y=124)

The line y := !y + 1 is interesting. What's happening here is we're using the old referenced value for y to create a new, incremented value. y then references this new value (124). The old value is forgotten by y, but is not changed (x still = 123). The analog here is pointers, e.g., from C or C++: the pointer is changed, not the thing the pointer used to point to. As you can see from the example above, the := operator is a shorthand for assigning to contents, and ! is a shorthand for reading its value. The fact the := does not change the references value is somewhat counterintuitive, since reference cells behave very much like pointers otherwise. The net net of all this? Use mutable when you can, and reference cells otherwise. You can use mutable so long as the mutable variable is in local scope.

Defining Generic Types


In an earlier chapter, we discussed generic functions, the mechanics of which are largely handled by F#'s sophisticated type inference system and automatic generalization facilities. We also discussed that type abbreviations can contain generic designations. To finish the swing on generics, I want to mention that F# supports our defining our own generic types, just like the generic types that ship with F# and those in the .NET Base Class Library (BCL), e.g., List. Let's suppose, for example, that I want to create a new type, a Stack that can contain any type of object. While there are several ways to skin that cat, one of the prevalent F# idioms is to define a type-parameterized DU. To follow that idiom, we would define our type as a generic discriminated union, as shown:
type 'a Stack = | EmptyStack | StackNode of 'a * 'a Stack

This definition creates a generic data structure. The leading apostrophe in 'a is important. It's a required literal part of the syntax. Simply using the letter a without a leading apostrophe will not work. The 'a preceding Stack tells us (and, as importantly, the compiler) that this type is generic, which means the type can be deduced when the DU constructor is invoked. When we supply a data element to the Stack, F# infers the particular type of the Stack and binds it to 'a . Note the 'a is a placeholder for a concrete type. It is replaced by the type supplied by the constructor's caller. We now have a Stack containing one element, and the Stack expects all future elements to be of the same type. Now that we've created an instance of a Stack, one with a real type, we have created a constructed type. The following code snippet shows 3 constructed types based on the generic Stack type:
let iStack = StackNode(3, StackNode(5, EmptyStack) let fStack = StackNode(2.0, StackNode(1.0, EmptyStack)) let sStack = StackNode("world", StackNode("hello", EmptyStack))

The only reason I mention the term constructed type, is because it shows up in some F# literature. There's nothing particularly significant about that term. A note about syntax. F# also supports an angle bracket syntax when dealing with generic type parameters. We will discuss this more in Chapter 13; however, for the curious, we could define the above Stack as follows:
type Stack<'a> = | EmptyStack | StackNode of 'a * 'a Stack

The two forms are logically identical. The are created identically and behave the same way.

What You Need to Know


F# supports a rich set of aggregate types including enumerations, records, discriminated unions, structures and classes. We will cover structures and classes later. In F#, you can define your own types via type abbreviations, e.g., t type student = string * float * bool. Type abbreviations are aliases. When you define a type via a type specifier, you can include generics. Enumerations represent named values. Each name must have an associated value. Records represent simple aggregates of name-value pairs. Generally, a record's name-value pairs are logically or semantically related. You can enhance record types with functions (discussed later) and custom operators. A discriminated union is an aggregate type whose instances resolve to one of its discriminants. In functional languages, discriminated unions are used in places where OO languages might use lightweight class hierarchies. Option is a pre-defined discriminated union in F# that's used when a given expression has the potential for returning "no

value", e.g., when you read from a database. F# supports reference cells, which are wrappers around mutable values. They are used when the semantics of the language prevent the explicit use of mutable, such as when closures are formed. F# supports your defining your own types, including generic types.
[1]

Type abbreviations are much like typedefs in C/C++. This is possible because for each discriminator defined, under the covers F# generates a simple class with a constructor that expects arguments of the speficied types. [3] Adapted from F Sharp Programming Wikibooks (http://en.wikibooks.org/wiki/F_Sharp_Programming/Discriminated_Unions) [4] Defined in the Microsoft.FSharp.Core.Option (http://research.microsoft.com/enus/um/cambridge/projects/fsharp/manual/fsharp.core/microsoft.fsharp.core.option.html) module. [5] There is another function, contents, that is used for OCaml compatibility. it does the same thing as Value .
[2]

Chapter 12 Pattern Matching & Active Patterns


Introduction
Many times in programming we need to examine data structures and their values, and test them against one or more conditions. When these conditions are met, we perform certain computations, trigger transformations, or take particular actions. To accomplish these types of operations in F#, you can use a series of ifthenelse statements; however, pattern matching offers greater power and flexibility, and goes well beyond more primitive ifthenelse constructs.

Patterns
Before we can talk about pattern matching, it makes sense to first define what patterns are. Patterns (http://msdn.microsoft.com/enus/library/dd547125(VS.100).aspx) are rules for transforming data. We use patterns throughout F# to do the following types of things: compare data with a logical structure decompose data into its constituent parts extract information from constructs in various ways Whereas other languages provide basic value-based decision and branching mechanisms, patterns augment and improve upon this ability. They provide the basis for making these same types of decisions based on the structure of the data and its type we well. This ability enables you to elegantly deconstruct and extract information from varying constructs in a clean, efficient, and succinct manner something that is difficult to do in more traditional languages.

Pattern Matching
Pattern matching is the act of comparing a test expression with one or more patterns. F# is quite flexible with respect to the types of test expressions it's capable of matching against. These include literals, constants, single variables, multiple variables, tuples, array, lists, enumerations, discriminated unions, records, and classes (to be covered) and combinations thereof. For the rest of this chapter, we'll look at how pattern matching works, and the types of things you can do with it.

Using match
The workhorse of pattern matching is the match expression, which combines branching control with computation. The match expression takes the following general form:
match test-expression with | pattern1 [ when condition ] -> result-expression1 | pattern2 [ when condition ] -> result-expression2 | ...

Throughout this section, I will use the terms as specified in the general form above. To be clear, let me explain the various components:

match expression. This is the entire construct, from the word match to the end of the final branch (the code after the vertical bars (|)). test-expression. This is the input to the match expression. It may be a numeric constant, character, a string, a manifest constant, a simple variable, an array, etc. Most of F#'s types can be used as test-expressions. pattern. This is the contour of symbols against which the test-expression is evaluated. The pattern specifies how to try to deconstruct the test-expression. when condition. This is a predicate that qualifies a pattern match. In order for a match to be considered successful, the pattern must satisfy the test-expression and the when condition, if present (it's optional) must evaluate to true. result-expression. This is the expression that F# returns when the corresponding pattern is considered to be a match for the test-expression under consideration.
Pattern matching via the match expression provide a "small language" to describe the structure and the types of values you want to match against. I find it helpful to think of patterns as distant cousins to regular expressions. When the match expression executes, F# compares the given test-expression with each of the specified patterns in turn. When the matches a pattern, the corresponding result-expression is evaluated and it returns a value. This value is the result of the entire match expression. Once a match is found, F# stops evaluating. This means that you need to be aware how you order your patterns you want to put the most specific patterns earlier in the pattern chain, and the more general ones towards the end; otherwise, the later ones will never be tested. The entire match expression is limited to a single type, meaning that all result-expressions must eventually resolve to the same type.

test-expression

Matching Anything - The Wildcard Pattern


The simplest of patterns is called the wildcard pattern. The wildcard pattern is specified as a single underscore character (_) and matches any test-expression. Thet
match 3 with | _ -> printfn "wildcard matches anything." match "f#" with | _ -> printfn "strings work, too" match [1;2;3] with | _ -> printfn "arrays work fine"

You can match the wildcard pattern againt all legal test-expression types, and it will always yield a postive match. Since the wildcard pattern "matches anything", it's normally used as the very last pattern in match expressions. It's F#'s way of dealing with the fact that the test-expressionmatched none of the other patterns. Using a wildcard pattern prevents F# from needing to throw a MatchFailureException when it exhausts its search for a positive match; instead, it will reach the wildcard pattern and return the default expression.

Matching Constants
We can match constant test-expressions against constant patterns. A constant pattern only matches when it equals the testexpression.
\\A constant pattern only matches when it equals the test-expression match 3 with | 2 -> "Never matches." | 3 -> "OK. This matches."

In this example, F# compared the test-expression 3 with the pattern 2, found no match, and continued down the list of patterns in lexical order. When it found the pattern 3, it calculated a valid match, and evaluated the corresponding result-expression, OK. This matches.. The return type of the match expression is string. Although this example works fine, you should be aware that if you compile or run it in the F# Interactive Console, F# will report the following warning:
Program.fs(4,11): warning FS0025: Incomplete pattern matches on this expression. For example, the value '0' may indicate a case not covered by the pattern(s).

This means that F# has detected that it's possible for a caller to pass in a test-expression that does not have match any of the patterns specified. We can handle this by using the wildcard pattern as a catch-all pattern:
match 3 | | | with 2 -> "Never matches." 3 -> "OK. This matches." _ -> "Catch-all. Will never get here."

Overall, this isn't a very compelling example, and if all you could do was pattern match over literals, pattern matching wouldn't be very useful. Let's look at how symbols and manifest constants are used in conjunction with matching.

Matching Manifest Constants


In the following code, we define 2 manifest constants, GOLDENRATIO and LOG10. We then want to write match expression that uses these constants as patterns.
[<Literal>] let GOLDENRATION = 1.618 [<Literal>] let LOG10 = 2.303 let foo x = match x with | GOLDENRATION -> "The Golden Ratio" | LOG10 -> "Log 10 is Used Everywhere"

When you want to match against a manifest constant, you need to tell F# that the pattern is actually a literal and not a symbol pattern. You do this using the LiteralAttribute. If you fail to specify [<Literal>], the pattern matching engine will match the testexpression against any symbol and will always match the first pattern it finds. Here is the same example without the benefit of the [<Literal>] attribute.
let GOLDENRATION = 1.618 let LOG10 = 2.303

let foo x = match x with | GOLDENRATION -> "The Golden Ratio" | LOG10 -> "Log 10 is Used Everywhere" let result = foo 1.23

When run in the F# Interactive Console, we get the following result:


val val val val GOLDENRATION : float = 1.618 LOG10 : float = 2.303 foo : 'a -> string result : string = "The Golden Ratio"

The test-expression 1.23 has somehow matched the GOLDENRATIO pattern, even though the values are not equal. What happened? The pattern matching engine didn't know it was supposed to match 1.23 against the value 1.618; therefore, it treated GOLDENRATIO as a new unbound local symbol which can bind to anything. In fact, the expression let result = foo "abc" would have worked, too! This is probably not the way we want the match to behave. The moral of the story is when your patterns are manifest constants, make sure to have attributed these constants with [<Literal>] . When used in this way, pattern matching is akin to a basic switch statement in C-based languages. Just to show pattern matching using different data types, let's look at another example that uses strings for the test-expression and patterns.
\\Patterns and test expressions can be strings, too. match "hello" with | "goodbye" -> "Never matches." | "hello" -> "Always matches." | _ -> "We'll never get here."

Matching Symbols
Patterns

can be symbols as well. Symbols match the "shape" of the test-expression data. In the following example, the pattern x will always match the test-expression 3, since the single value 3 can be positively bound to the pattern x they "match up" in structure.
\\Patterns always match with a symbol that's not an enum, DU, or literal constant match 3 with | x -> "This always matches here." | 3 -> "This would match, but we never get here!" | _ -> "This would match, but we never get here either!"

Value Binding
When comparing a test-expression against a pattern, F# automatically assigns the test-expression's value(s) to the symbol(s) specified in the associated pattern. For example, when we pattern match against 3 and x above, x is initialized with the values from the test-expression, 3. We call this automatic value-to-symbol association value binding. In general, value binding is a powerful by-product of matching because it enables the subsequent use of the values in downstream calculations. This economy of expression makes for succinct, expressive code. It is used quite naturally in many pattern matching scenarios. When symbols are used as patterns, they can be leveraged in result-expression calculations and as return values:
match 3 | | | match with x -> x + 2 3 -> 6 _ -> 7

\\returns 5 \\we'll never get here, and never return 6 \\we'll never get here, and never return 7

expressions can act surprisingly when symbol patterns use the same name as other values that are in scope. Let' look as a few examples:
\\Local let x = match 3 | value x 5 with x -> x \\returns 5!

\\Returns 5, because x is not a local pattern symbol. y is, so y is bound to 3, \\but not subsequently used. We might as well have used a wildcard instead of y \\here.

Qualifying Matches Using When Guards


F# enables us to augment patterns with conditions called when guards. When guards are Boolean checks, a.k.a., predicates, which allow us to qualify patterns. When guards are used in conjunction with patterns to constrain what constitutes positive matches. The following example demonstrates their use:

let sign x =

match x with | x when x < 0 -> -1 | x when x = 0 -> 0 | x when x > 0 -> 1 | _ -> int nan

\\match \\match \\match \\nan =

only only only "not

when x < 0 when x = 0 when x > 0 a number" from System.Double.NaN

With when guards, the wildcard pattern is sometimes used so that the guts of the pattern match is based on the guard condition. It is not uncommon, for example, to see a function like sign (above) implemented like this:
let sign x =

match x with | _ when x < 0 -> | _ when x = 0 -> 0 | _ when x > 0 -> 1 | _ -> int nan

\\match \\match \\match \\nan =

only only only "not

when x < 0 when x = 0 when x > 0 a number" from System.Double.NaN

Here, we use the wildcard pattern to match whatever test-expression is passed into the match expression. We then base a positive match on the when guard's return value. We can leverage when guards as part of any pattern test. In the following example, we use a local binding in conjunction with a when clause. Note that the when clauses uses the bound value of x, not the externally defined x:
let x = 5 match 3 with | x when x = 5 -> 6 | _ -> x

\\here x=3, not 5, so we fail the when clause \\this match succeeds and returns 5 for the match expression

Matching Patterns and Types


Patterns are not limited to single literals or variables. We can use patterns to match against tuples, list constructs, arrays, and various user-defined types. The following examples demonstrate using pattern matching with the types we've covered so far.

Matching Multiple Variables


Our test-expressions can contain more than one variable, as can the patterns we match against. In the following example, our test-expression contains two variables an int and a string and returns a Boolean.
let allowAccess userid pwd = match userid, pwd with | 123, "123" -> true | 505, "xyz" -> true | _, "**9" -> true | 411, _ -> true | _ -> false

Matching Tuples
bool

F#'s pattern matching engine is also capable of matching against tuples. The following function accepts a tuple of type bool * and uses the tuple as its test-expression.
let orTable(b1, b2) = match (b1, b2) with | (true, true) -> true | (true, false) -> true | (false, true) -> true | (false, false) -> false

In this example, we did not need to provide a default branch, since we've covered all possible pattern combinations. F# recognizes that our patterns are logically complete, so does not issue a warning or an error.

Matching Arrays
When we match using an array pattern, in order to match successfully, the test-expression must be an array of the same size and makeup as the pattern being evaluated, and must contain the elements in the same order as the candidate pattern.
let digitmsg a = match a with | [|0;1|] -> "binary digits" | [|2;4;6|] -> "some even digits" | _ -> "who knows?"

If we were to call digitmsg with [|0; 1|], we'd get a postive match, whereas calling it with [|1;0|] would result in a non-match. The patterns used with the match expression must all be of the same type. For example, the following produces a type-based error:
\\Match array (error)

let digitmsg a = match a with | [|2; 4; 6|] -> "some even digits" | [|"test"|] -> "does it work?" \\error: used string, expected int | _ -> "who knows?"

Note that we can use the wildcard pattern to match individual array elements:
let flower a = match a with | [|"roses"; _|] | [|_; "violets"|] | [|_; _|] | _

-> -> -> ->

"roses are red" "violets are blue" "this matches any two things" "catch-all"

Matching Enums
You can use pattern matching to match against enumerations. The enumeration pattern must use the entire qualified name:
type Protocol = | UDP = 0 | TCP = 1 let sendPacket proto packet = match proto with | Protocol.UDP -> "sending UPD" | Protocol.TCP -> "sending TCP" | _ -> "unknown protocol"

Matching Lists
F# also supports working with list-based patterns. The lists can be processed using literals, wildcards, and recursion:
\\Lists can be matched as literals match [1;2;3] with | [1;2;4] -> "doesn't match" | [3;2;1] -> "doesn't match, order counts" | [1;2;3] -> "OK - a match" | _ -> "should never get here" \\The contents of the list can be any valid type, e.g., strings or tuples. \\Remember that all list elements must be of the same type, e.g., all strings. let famousDuo pair = match pair with | ["bonnie"; "clyde"] | ["adam"; "eve"] | ["ozzie"; "harriet"] | ["gilbert"; "sullivan"] | _

-> -> -> -> ->

true true true true false

let isFamous = famousDuo ["adam"; "eve"] \\order matters. ["eve"; "adam"] would return false. \\Lists can be matched with missing literals, by using a wildcard match [1;2;3] with | [1;_;4] -> "doesn't match in the last element 3 vs. 4" | [1;2;_] -> "OK - the underscore matches to 3" | [_;2;3] -> "we'll never get here, but this would match if we did" | _ -> "should never get here" \\Symbols can be used in patterns to match part of a list match [1;2;3] with | [1;x;4] -> "Doesn't match in the last element 3 vs. 4" | [1;2;x] -> "OK - the x is bound to 3 - in this line only!" | [x;2;3] -> "We'll never get here, but this would match if we did" | _ -> "Should never get here"

As you'll recall, when we process lists, we normally do so recursively. To support recursive pattern matching on lists, F# supports two additional patterns:
[]. This is the empy-list pattern. It used to test a list to see if it's empty. pat::pat. This is the cons pattern and is used to match the head and tail

of the list.

In the following example, we create a recursive function that counts the number of elements in the given list. Although contrived, this example helps demonstate the empty-list and cons patterns:
let rec count lst = match lst with | [] -> 0 | [_] -> 1 | [_;_] -> 2 | _ :: t -> count t + 1

\\empty list -> 0 elements \\any one thing -> 1 element \\any two things -> 2 elements \\cons pattern. count recursively.

Let's take a look at another list-based example that uses the cons pattern to sum up all the numbers in the collection:
let rec sum theList = match theList with | [] -> 0 | h :: t -> h + sum t let theSum = sum [0..2..100] \\2550

Using pattern matching in conjunction with recursive list processing is a common idiom in F# programming.

Matching Records
The F# pattern matching engine also recognizes records. To work with pattern matching records, you can match on individual record fields or combinations thereof. In the following example, we define a record type Employee and a function calcRaise. We then use various combinations of patterns to calculate raises based on a various criteria.
type Employee = { rank: string; name: string; salary: float } let calcRaise emp = match emp with | { rank="manager"; name="Smith" } -> emp.salary * 1.10 | { rank="manager"} when emp.salary <= 75000.0 -> emp.salary * 1.20 | { rank="indi"} -> emp.salary * 1.30 | _ -> 0.0

Matching Discriminated Unions


Last but not least, let's take a look at using pattern matching in conjunction with DUs. In this next example, we demonstrate how to match against a DU's discriminator using a variety of techniques. We also demonstrate a somewhat common idiom of nesting match expressions:
type Weapon = | Knife of int | Sword of int | Mace of int * bool let k = Knife(100) let s = Sword(500) let m = Mace(750, true) \\true=is magic let showDamage w = match w with | Knife(damage) -> printfn "knife caused %d damage points" damage | Sword(_) -> printfn "sword caused 1000 damage points" | Mace(damage, isMagic) -> match isMagic with | true -> printfn "mace caused %d damage points" (damage * 5) | false -> printfn "mace causes %d damage points" damage showDamage k showDamage s showDamage m

The id Pattern
F# also supports the id pattern, which is a mechanism for explicitly invoking value binding. In the following example, we use the id pattern to make a copy of a list, binding the list's values to new identifiers, by position:
let lst = [1; 2; 3] let [x; y; z] as lst2 = lst

The id pattern is actually used with let and not match. It also includes using the keyword as, as shown above. You can think of the id pattern as being invoked via letas. After executing the above example, x = 1, y = 2 and z = 3. If the lists were of different sizes, F# would have generated a compile error.

Pattern Groups
In addition to being able to perform single and qualified matches, e.g., with when guards, we can also group matchues using "or" and "and" patterns. First, let's look at "or" patterns, which allow us to chain together alternative patterns and pick among them. The "or" pattern uses the verical bar (|) to separate its alternatives. The following example uses an "or" pattern to match countries with currencies:
\\Matching one of several alternatives with "or" let currencyForCountry (country: string) = match country.ToLower() with | "us" | "east timor" | "ecuador" | "panama" -> "U.S. Dollar" | "portugal" | "spain" | "austria" | "belgium" -> "Euro"

| _ -> "unknown currency"

country.ToLower()

In this example, we explicitly declare the type of the argument country to be string. We need to do this so that the call to compiles correctly; otherwise, the F# compiler complains that it cannot fully determine country's type, and thus cannot guarantee that the ToLower function exists.

In addition, when we explicitly declare function argument types, as in this example, we must surround the arguments and their types with parens to ensure F# evaluates them properly. If we omit the parens, F#'s order of evaluation rules cause it to consider country a generic vs. its assigned type. To complement the "or" pattern, F# offers the "and" pattern. The "and" pattern requires that the test expression matches two or more separate patterns. The types on both sides of the "and" pattern must be compatible. The "and" patterns uses the ampersand (&) symbol to join the associated patterns. The following example was taken from the MSDN documentation on patterns (http://msdn.microsoft.com/en-us/library/dd547125(VS.100).aspx) :
let detectZeroAND point = match point with | (0, 0) -> printfn "Both values zero." | (var1, var2) & (0, _) -> printfn "First value is 0 in (%d, %d)" var1 var2 | (var1, var2) & (_, 0) -> printfn "Second value is 0 in (%d, %d)" var1 var2 | _ -> printfn "Both nonzero."

We can then call the detectZeroAND function like so:


detectZeroAND detectZeroAND detectZeroAND detectZeroAND (0, 0) (1, 0) (0, 10) (10, 15)

Alternative Functional Representation of match


F# offers another, shorthand form of pattern matching syntax and it does not use the match keyword. Instead, this form of pattern matching uses the keyword function to introduce a lambda expression (the "pattern matching function") in which the matching is performed immediately on the lambda's argument. In the following example, we create a pattern matching function that accepts a string representing a meal, and returns the corresponding price as a floating point value:
let menuPrice = function \\implicit un-named parameter | "breakfast" -> 3.49 | "lunch" -> 8.75 | "dinner" -> 18.50 | "drink" -> 2.50 | _ -> 0.0 let cost = menuPrice "lunch" + menuPrice "drink"

Note that the function's argument is implicit and its type is inferred by the type of the patterns (a string in this example). Because the argument is implicit, there can be only one[1]. If we want to use the lambda pattern matching syntax, and still need to pass multiple values into our test-expression, we can use tuples or other aggregate data structures like discriminated unions. In the following example, we use a tuple to represent a point in some arbitrary square whose upper-left point is (0,0) and whose lower right point is (1.0,1.0).
let isPointInSquare | (0.0, 0.0) -> | (1.0, 1.0) -> | (a, b) when a | _ -> false = function false false > 0.0 && a < 1.0 && b > 0.0 && b < 1.0 -> true

As demonstrated here, we have access to the implied lambda argument. We can see this clearly via the (a, b) pattern in this example. When we specify the pattern (a, b), value binding maps the lambda's input values to the labels a and b respectivley.

Active Patterns
With the pattern matching mechanisms we've discussed so far, the test-expressions and the patterns have been completely static, i.e., they are fixed at compile time and do not change during the execution of the program. What if we'd like to make our patterns "come alive" so that we could programmatically control and change them during the process of matching? Well, we can via active patterns. The fact that these patterns can change under program control is what makes them "active."

Simple Transformations
The simplest form of an active pattern acts as a transformation. It accepts a single argument as input and transforms it in some

way. The transformed value is the pattern used in the match expression. In the following example, we use an active pattern that converts its input, assumed to be a temperature in Fahrenheit, to the equivalent Celsius measure:
let (|F2C|) f = (f - 32.0) * (5.0 / 9.0)

This active pattern looks exactly like a regular function. The only difference is how the function's name is bracketed by a set of vertical bars, colloquially called "banana clips." The banana clips tell the F# compiler that we intend to use this function (active pattern) in conjunction with pattern matching, and that it's not a general purpose function to be called arbitrarily. We need active patterns to implement this type of behavior because regular functions cannot be used as pattern candidates. So, active patterns are like functions called in the context of pattern matching. We place them lexically where we normally place static patterns; however, when F# sees an active pattern vs. a static pattern, it invokes the active patternand uses the function's result as the pattern value. We can see how to use our F2C active pattern in the following example:
let test (f: float) = match f with | F2C c when c > 30.0 -> printfn "it's hot %f" c | F2C c when c > 20.0 -> printfn "it's temperate %f" c | F2C c when c > 10.0 -> printfn "it's cool %f" c | _ -> printfn "it's getting cold!"

Notice here we're using our active pattern F2C where we'd use a normal, static pattern. The variable f is used as the input to active pattern, and c is the output. To process the active pattern, the match expression compares the value of f with the result of calling F2C c, and prints out a corresponding message.

Arbitrary Decomposition
In addition to converting single values, we can use active patterns to decompose most any data structure in a customized manner. To perform custom decomposition, we define "named partitions" that subdivide the data using criteria that we define. We can then use these named partitions in subsequent matching clauses. Active patterns come in two flavors: complete active patterns and partial active patterns. We will look at each one in turn.

Complete Active Patterns


While it is very convenient to think of active patterns as functions, there's one wrinkle. Whereas functions have a single name, active patterns can have multiple names, or more accurately, multiple identifiers. Active patterns with single names, a.k.a., single identifiers, such as F2C above, are more formally known as single-case active patterns. In the general case, active patterns can include more than one identifier and are known as multi-case active patterns. Single-case and multi-case active patterns that use all of their inputs are called complete active patterns. Let's take a look at the following example, where we define a complete, multi-case active pattern:
let (|Child|Teen|Adult|Senior|) age = if age < 13 then Child elif age >= 13 && age < 18 then Teen elif age > 18 && age < 60 then Adult else Senior

This active pattern includes 4 identifiers: Child, Teen, Adult, and Senior. It is often helpful to think of these as "buckets" or partitions into which we'll assign inputs. We also define an input argument, age, that we use as the basis of the partitioning. In the following example, we use this active pattern to process a list of people's ages:
let rec showPeople p = let mutable tail = [] match p with | [] -> printfn "<done>" | h :: t -> printf "%d = " h tail <- t match h with | Child -> printfn "child"; | Teen -> printfn "teen"; | Adult -> printfn "adult"; | Senior -> printfn "senior"; showPeople tail

We can now test the showPeople function as follows:


showPeople [4; 10; 42; 15; 34; 19; 66; 48; 55; 32; 21; 18; 81; 74; 65; 14]

The thing that makes these patterns "active" is the fact that a function executes in order to partition the input. Note that an active pattern identifier must begin with an uppercase character. This is one of the few places where F# dictates case

outside of its keywords.

Partial Active Patterns (Some and None)


Although it may sounds complex, a partial active pattern is a special case of a single-case active pattern that returns an option type, i.e., it either returns Some or None. A partial active pattern is characterized by the fact that it returns an option and F#'s pattern matching mechanisms recognize that a Some characterizes a valid match, while a None does not; otherwise, it behaves exactly like the active patterns we've discussed already. T o define a partial active pattern, you append a wildcard character (_) to the end of the identifier inside the banana clips. The following example, taken from an article by Pickering (http://www.infoq.com/articles/Beyond-Foundations-FSharp) , demonstrates a partial active pattern used to match different date formats:
open System let invar = Globalization.CultureInfo.InvariantCulture let style = Globalization.DateTimeStyles.None let (|ParseIsoDate|_|) str = let res, date = DateTime.TryParseExact(str, "yyyy-MM-dd", invar, style) if res then Some date else None let (|ParseAmericanDate|_|) str = let res, date = DateTime.TryParseExact(str, "MM-dd-yyyy", invar, style) if res then Some date else None let (|Parse3LetterMonthDate|_|) str = let res, date = DateTime.TryParseExact(str, "MMM-dd-yyyy", invar, style) if res then Some date else None let parseDate str = match str with | ParseIsoDate d -> d | ParseAmericanDate d -> d | Parse3LetterMonthDate d -> d | _ -> failwith "bad date" \\throws exception (covered later) let let let let d1 d2 d3 d4 = = = = parseDate parseDate parseDate parseDate "05-23-1978" "May-23-1978" "1978-05-23" "05-23-78" \\shoud fail

In this example, we use partial active patterns to parse a given date string. Since the string may be in one of several formats, we define several active patterns, one per date format. Active patterns are also useful when implementing "and" patterns. Recall from Chapter 11 that "and" patterns consist of multiple match clauses. To be considered a successful match, the input must satisfy all of the clauses. In the following example, we use active patterns to succinctly implement an "and" pattern to ensure that a given number is a both a multiple of 3 and is even:
let (|MultipleOf3|_|) n = if n % 3 = 0 then Some(n) else None let (|Even|_|) n = if n % 2 = 0 then Some(n) else None let checkNum x = match x with | MultipleOf3 a & Even b -> printfn "%d is a multiple of 3 and is even." x | _ -> printfn "%d is just %d" x x

A couple of important things to note. First, remember that every active pattern receives at least one input the test-expression in the match expression. In the checkNum example above, the test-expression is x. Second, when a pattern returns a value, we capture it in an output variable. This is the purpose of the a and the b in the checkNum function above. If we omit a, for example, the compiler will complain that we have an expression of type unit being used with an expression of type int. In other words, the pattern is returning a value (the int) and we've no place to put it. The placement of active pattern inputs and output can be a little bit confusing. We're used to specifiying input arguments explicitly and placing them after the name of the function. In the case of active patterns, the input is implicit via the testexpression, and the variable following the active pattern name is actually the output (the result of the active pattern executing).

Parameterized Active Patterns


Active patterns accept at least one input argument the test-expression a.k.a., the data being matched via the match expression. Active patterns can accept additional arguments as well, in which case they are called parameterized active patterns. These additional arguments allow us to constrain and/or specialize the processing our active patterns performs. In the following example, we define an active pattern that enables us to parse a substring from an input string:
let (|StringMatches|_|) (mytarget : string) (mystring : string) = if (mystring.Contains(mytarget)) then Some(true) else None

We can use this active pattern as follows:

let stringContains str target = match str with | StringMatches target result -> printfn "%s contains %s" str target | _ -> printfn "Substring not found"

Here again, I'd like to emphasize the somewhat confusing placement and binding of active pattern arguments. In this example, the test-expression str serves as input to the StringMatches active pattern. The match's test-expressionalways binds to the last (right-most) parameter in the the active pattern. This means that in this example, str binds to the active pattern's mystring argument. In addition, the target argument from the match expression binds to the mytarget argument in the active pattern, and the result variable binds to the active pattern's Some/None return value.

What You Need to Know


Patterns are rules for mapping and transforming input data. F# uses pattern matching to map patterns to values. The match expression is used to invoke pattern matching. The match expression is like a set of ifthenelse or switch statements, but more powerful. You use the wildcard pattern ( _) to match "anything." With the match expression, you can match constants, single values, multiple values, tuples, arrays, lists, and cons (::). You can also match records, discriminated unions, object types/constraints, and nulls. You can combine match expressions with "or" and "and" constructs. You can use when guards to augment patterns with predicates. There is an alternative form of the match expression that uses a lambda via the function keyword. This lambda accepts a single, implicit argument available to the body of the lambda. Active patterns enable us to define a function that F# calls when pattern matching. The result of the function is used as the pattern F# uses to match against the test expression.
[1]Like

in Highlander, the movie.

Chapter 13 Object-Oriented Programming, Part I


Introduction
For the past 15 years or so, object-oriented (OO) design (OOD) and programming (OOP) has been the lingua franca of mainstream development. As a multidisciplinary language, F# supports a full complement of OOP constructs including structures, classes, interfaces, inheritance, etc. In this chapter, we'll look at how to work with existing .NET types, as well as how to build our own OO types using the mechanisms F# supplies. Please note that the chapters on OOP assume familiarity with the concepts and terminology of encapsulation, classes, object instances, inheritance, and polymorphism.

Access Specifiers
F# supports common OO access specifiers, which give structures (and classes, etc.) a way to control how clients can interact with them. F# supports the following access control keywords:
public all callers can access internal callers within the same assembly have access private callers within the same enclosing type or module

can access

If you've been programming in OO languages for any length of time, your immediate question is "What about protected access?" F# may support the protected keyword in the future; however, if you try to use it in code today, the F# compiler will tell you it's reserved for future use; therefore, as of this writing, this is no protected access. We use access specifiers throughout the rest of this chapter and throughout the rest of this book.

Structures
The first step down the road toward OOP takes us face to face with structures. A structure is a logically-related set of data and methods that exhibits a low-overhead representation on the stack. A structure is a .NET value type, which means it uses pass-byvalue semantics, i.e., a copy is made when the structure is passed around. In the following example, we define a simple structure Book containing several simple fields:
[<Struct>] type Book = val Author: string val Title: string val Price: float

All structures are decorated with the [<Struct>] attribute, which instructs the F# compiler to apply value semantics.

Using Fields
Structures are made up of fields, constructors, and optionally, interface implementations. To declare fields, we use the keyword val. In the example above, the structure Book defines three fields: Author, Title and Price. Fields may be static and may be declared public, internal or private (see the next section of this chapter for the details on these access specifiers). The default access for fields is public. Fields may also be mutable. The general form of the val expression is:
[ static ] val [ mutable ] [ access-modifier ] field-name : type-name

To access a structure's fields, you use dot ( .) notation.

Creating Instances
Now that we have a structure, let's talk about how to work with it. In general, we work with structures by creating instances of them via the keyword new, as demonstrated below:
let b = new Book()

This creates a new instance of the Book structure and assigns it to the identifier b. When F# creates the new book instance b, it needs to initialize the three fields Author, Title, and Price. To initialize these field, F# needs to invoke a constructor. The first thing F# will do is to look for a custom constructor. If it finds one, it will invoke it. If is does not find one, it will use the default constructor that it has generated on our behalf behind the scenes. This defaul constructor initializes all numeric types to 0 and all non-numeric types to null. Since we have not yet defined a custom constructor for Book, F# invokes the default constructor and sets Author to null, Title to null and Price to 0.0.

Mutability
Since Book's fields are not specified as mutable, they will remain at their default values throughout their existence. If you need the

ability to modify a field over the lifetime of the application, you must declare it mutable, as in the following example:
[<Struct>] type Book = val Author: string val Title: string val mutablePrice: float

\\now, we can adjust Price

Given this new definition of the Book structure, we can create instances of Book that allow the Price field to change over time. In order to actually modify mutable fields, the structure instance itself must be created using the mutable keyword, as in the following example:
let mutable b = new Book() b.Price <- 11.50 \\note use of "mutable b" here \\updated via destructive assignment

Mutability is granted on a field-by-field basis. Given the code above, the following line will generate a compiler error:
b1.Author <- "Jones" \\error - Author not mutable

Custom Constructors
In addition to fields, structures can define one or more custom constructors that are used to initialize their fields to default values. As mentioned previously, if you choose not to supply a custom constructor, the F# compiler will generate one on your behalf. A custom constructor is defined using the keyword new followed by a list of arguments. The arguments may include type information; however, if they do not, F# type inference will try to determine their types based on how they're used in the body of the constructor. In the following example, we update the Book structure to include an explicit, custom constructor:
[<Struct>] type Book = val Author: string val Title: string val Price: float new(a, t, p) = { Author = a; Title = t; Price = p }

A custom constructor enables a caller to pass in initialization arguments when creating a new structure instance, as shown here:
let b = new Book("Jones", "Happy Days", 11.45)

Note that the structure's fields do not need to be declared mutable in order to be initialized by the constructor. Explicit constructors can contain whatever arguments you need in order to initialize your structure. The only requirement is that the body of the constructor must initialize all of the fields. If your custom constructor fails to initialize all of the structure's fields, the compiler will generate an error. You can create multiple custom constructors, each taking a different set of arguments. Multiple constructors provide callers with a variety of creation options. As an example, let's update our Book structure to include two custom constructors:
[<Struct>] type Book = val Author: string val Title: string val Price: float new(a, t, p) = { Author = a; Title = t; Price = p } new(a, t) = { Author = a; Title = t; Price = 12.50 }

Given the above definition, we can now create book instances as follows:
let wt = new Book("Where the Wild Things Are", "Maurice Sendak", 9.50) let dr = new Book("The Girl with the Dragon Tattoo", "Stieg Larsson")

Of course, you can combine custom constructors with mutable fields, as in our final example:
[<Struct>] type Book = val Author: string val mutable Title: string val mutable Price: float new(a, t, p) = { Author = a; Title = t; Price = p } let mutable b1 = new Book("Smythe", "Money and You", 10.00) b1.Title <- "Money and Your Life" b1.Price <- 11.75

General Form

For the studious among us, a structure in F# takes the following form:
[ attributes ] [<StructAttribute>] type [accessibility-modifier] type-name = type-definition-elements[1]

Restrictions
A few restrictions to keep in mind " structures cannot participate in inheritance, cannot contain let or do bindings (we'll see what these are later), and cannot recursively contain fields of their own type, although they can contain reference cells that reference their own type.

Classes
Classes represent the "heart and soul" of OOP. Classes are types that represent entities in the domain model. In OO systems, computation is largely about creating instances of classes that contain state, i.e., objects, and manipulating this state over time. Please note that throughout this chapter, I will use the term "type" and "class" synonymously. At their core, these two terms represent the same construct and can be used interchangeable for all practical purposes.

Constructing Classes
Classes are user-defined types, introduced with the type keyword and a primary constructor. The primary constructor is defined as part of the type definition, and may or may not include parameters. The following demonstrates the humble beginnings of an F# class:
type Movie()

This tells us we have a new type called Movie and a primary constructor the takes 0 arguments ( ). Following the primary constructor definition is an = sign and the set of expressions that form the primary constructor's body. The body of the primary constructor can contain zero or more let bindings, which appear at the start of the type definition, before any member definitions. Let's take a look at a simple class definition that helps make all of this a reality:
type Movie() = let Title = "Paranormal Activity"

This bit of code does a few things: It introduces a new type called Movie It introduces a primary constructor that takes no arguments: Movie(). The empty parens introduce the primary constructor. It defines a single let expression that forms the body of the primary constructor. A let expression in a constructor implicitly defines a private field or private function. This means that the field Title is private in the above example. Attributes and accessibility modifiers are not allowed, therefore we cannot change the fact that Title is private it's an inherent property of the let binding as used in a constructor. To make things a little more interesting, let's define a new Movie class that creates 2 private fields in its constructor (OK, it's not that interesting, but bear with me).
type Movie() = let Title = "Paranormal Activity" let Director = "Orin Peli"

In addition to executing these let expressions, constructors can also execute arbitrary code using the keyword do followed by a series of expressions. In the next example, we create a class that prints out a few messages each time a new instance is created.
type Movie() = let Title = "Paranormal Activity" let Director = "Orin Peli" do printfn "Now showing %s by %s" Title Director printfn "We hope you enjoy the show!"

OK, so now we know how to specify a class, create a primary constructor, and execute instance-specific code the form of let and do expressions, sometimes referred to as let and do bindings. To create a fresh instance of a class, use the (optional) keyword new. This causes a new instance to be created and initialized with the constructor, e.g.:
let m = new Movie()

Note that using the keyword new is optional. I tend to favor it because it's explicit and conveys the purpose of the call; however, if it suits your style, you can omit it without error, e.g.:
let m = Movie()

Constructors with Arguments


When we create class instances, we generally want to pass in initialization information this is, of course, the whole point behind constructors. F# supports class constructors that accept arguments, as shown in the following example:
type Movie(t, d) = let Title = t let Director = d do printfn "Now showing %s by %s" Title Director printfn "We hope you enjoy the show!" Movie's

primary constructor now requires 2 arguments a title and a director. To create instances of Movies we can execute code similar to the following:
let ho = new Movie("The Hangover", "Todd Phillips") let pa = new Movie("Paranormal Activity", "Orin Peli")

If F# has trouble determining the types of the constructor's arguments, you can add explicit type annotations to them. For example, we can re-write the Movie type as follows, specifying the type of t and d:
type Movie(t: string, d: string) = let Title = t let Director = d do printfn "Now showing %s by %s" Title Director printfn "We hope you enjoy the show!"

Constructors that accept arguments are flexible relative to how these arguments work. First, the arguments of the primary constructor are in scope throughout the entire class declaration. This means that you can use the arguments passed into the primary constructor anywhere in the class. This also means that you do not need to store the arguments - you can treat them as implicit private fields. Second, by default, constructor arguments bind to their input by position, left to right; however, in F#, constructor arguments are implicitly named, making it easy for callers to access them directly and/or out of order, as in this next example:
type Movie(title: string, boxOfficeSales: decimal) = let netSales = boxOfficeSales * 0.90m \\these numbers are made up do printfn "%s grossed %f at the box office, for net sales of %f for the studio" title boxOfficeSales netSales let m = new Movie(boxOfficeSales=100000000m, title="Jaws")

Notice here that when we call the Movie constructor, we use the arguments' names to map the values explicitly vs. relying on their lexical ordering. We provide initial values using the arg-name=value syntax.

Constructors with Optional Arguments


Constructor arguments can be made optional by placing a question mark (?) before the parameter name. Optional arguments must come at the end of the argument list. Under the covers, F# wraps optional arguments in an Option (Some/None) type, making them naturally compatible with pattern matching. In the following example, we make the argument director optional:
type Movie(title: string, ?director: string) = let getDirector : string = match director with | Some(director) -> director | None -> "NOT SPECIFIED" do printfn "title = %s, director = %s" title getDirector

Typically, when processing optional arguments, we use pattern matching to check for the presence (or absence) of a value. When dealing with optional arguments, you often want to provide default values, in case the caller chooses to skip passing values into the function or method. To do this, you can use the function defaultArg. The defaultArg function takes the optional parameter as the first argument and the default value as the second. In the following example, the ticketPrice parameter is optional, and has a default value of 10.00.
type Movie(title: string, ?ticketPrice: float) = let ticketPrice = defaultArg ticketPrice 10.00 do printfn "Welcome to %s. Your ticket costs $%f" title ticketPrice

Overloaded Constructors
To provide different creation options its clients, a type can offer more than one constructor. You can define overloaded constructors using the following syntax:
new(arg-list) = constructor-body

In the following example, the Movie class contains 2 constructors: the primary constructor that accepts 2 parameters (string and float), and an overloaded constructor that takes 1 string.
type Movie(title: string, ticketPrice: float) = let Title = "[" + title + "]" do printfn "New movie created: %s" Title new(t: string) = Movie(t, 10.00)

You can define as many overloaded constructors as you want. Just keep in mind that the body of the overloaded constructor must call the primary constructor. Note that the let and do bindings defined in the primary constructor always execute, regardless of the constructor called.

Running Arbitrary Code in Overloaded Constructors


A class's primary constructor can execute arbitrary code via a do binding; however, an overloaded constructor cannot use this mechanism. In order to execute arbitrary code in an overloaded constructor, we need to use the then keyword, as shown in the following example:
type Movie(title) = do printfn "Welcome to the movie: %s" title new(t, d) = Movie(t) then printfn "Directed by %s" d

The then keyword allows us to run constructor-specific code, after the let and do expression from the primary constructor execute. The fact that the keyword is then is a reminder of the order in which the let and do constructs execute those from the primary execute, then those from the overload.

Self-Identifier
As part of the class definition, you can provide a self-identifier. A self-identifier is the way the class references itself in members (discussed shortly) such as properties and methods. In other words, it's the way an F# class represents "the current instance" of itself. In C++ and C#, the self-identifier has a special name this. In F#, there is no special name for the self-identifier you can choose to call it whatever you'd like. You can define a self-identifier in one of two ways. If you want the self-identifier to be available to the entire class, use the as keyword as part of the type definition. If you want the self-identifier to be available to a local member function, provide the name as part of the member declaration. In the following example, we embellish our Movie class with a self-identifier. We will see how to use it when we discuss members later in this chapter.
type Movie() as this = let Title = "Paranormal Activity"

Given the above declaration, the self-identifier this enables us to refer to "this instance of the class" anywhere in the class. Note that if the self-identifier is never used (as in the above example), the compiler will issue a warning:
warning FS1183: The recursive object reference 'this' is unused. The presence of a recursive object reference adds runtime initia lization checks to members in this and derived types. Consider removing this recursive object reference.

So, only use as <self-identifier> if you are going to use the self-identifier in subsequent constructs.

The Constructor Body Details of let and do


As we've seen, the bodies of constructors are made up of a series of let and do expressions. Let's (no pun intended) take a closer look at their general syntax and capabilities.
let

In a class constructor, a let expression takes the following form:


\\Field [static] let [ mutable ] binding[2] \\Function [static] let [ rec ] binding

A let expression can define a static or non-static class member either a field or a function. static members are those that are defined on the class itself vs. on objects of the class. As you can see from the above syntax, let expressions can create mutable and non-mutable fields, and can create recursive and non-recursive functions.

We contrast static let bindings with instance let bindings. static let bindings are guaranteed to execute at some point before the first instance of the class is created. They only execute once for the lifetime of the class. Up to this point, we've used let to define private fields only. We can also use let to define private functions. These functions are accessible only to the class itself. In the following example, we use let to define a private function, calcAdmission on the Movie class.
type Movie() = let Title = "Paranormal Activity" let calcAdmission numPeople = float numPeople * 10.25 do printfn "If 4 people went to see %s, it would cost $%5.2f" Title (calcAdmission 4)

do
F# class constructors can also include zero or more do bindings, which enable the execution of arbitrary code when an instance of the class is created. do bindings appear alongside let bindings, and take the following form:
[static] do expression static do bindings are guaranteed to execute before the first instance of the class is created. They are only executed once for the lifetime of the class. The combination of static let and static do bindings form the "static constructor" of the class, and are run once, before the first instance of the class is created.

Because let bindings initialize private fields of the class, do bindings generally appear after them lexically. This enables the do bindings to access the fields that the let bindings have just initialized. Note that if your non-static do bindings need to access members of the class to execute correctly, they can do so if the class defines a self-identifier (see next section) and all access to the class's member are made via the self-identifier. The net net of this binding story is that, together, the let and dobindings form the body of the primary constructor. The nonstatic let and do together form the instance constructor, while the static let and do together form the static constructor.

Alternate Field Creation Semantics


When you create class constructors, you can use an alternate mechanism to create fields: the val keyword. To use the val keyword to create fields, we must adhere to the following rules: use the [<DefaultValue>] attribute mark the field as mutable access the field through a self-identifier ( this in the example below). In the following example, we demonstrate this technique using the field director:
type Movie()= let title = "Jaws" [<DefaultValue>] val mutable director: string member this.SetDirector = this.director <- "Spielberg"

The pragmatic difference between using val vs. let is that you can specifiy the access mode (public, internal, private) for a value created with val, whereas with let, your fields are intrinsicly private and their accessibility cannot be changed[3].

Adding Members to Classes


Classes would be of limited utility if they only contained constructors and private fields. In practice, classes contain fields and functions (collectively called members) that form their public interface. You can define members on F# classes, structures, records, discriminated unions, and interfaces. We ignored adding members to these constructs earlier in the text to avoid confusion. After covering class members here, you will be in a position to add them to these other types as well. We will show examples of adding members to records, etc. as part of this chapter. Members are declared using the keyword member. Collectively, members represent a type's "public face"; therefore, they have public access unless declared otherwise. The form a member takes depends on the nature of the member, e.g., a property, method, etc. We will look at all of the possibilities in turn.

Properties
Properties are members that represent values associated with an object. They are like "smart fields" in that they have a "getter" method and a "setter" methods, a.k.a., accessors, defined. The full syntax for a property is as follows:
[ attributes ] [ static ] member [accessibility-modifier] [self-identifier.]PropertyName with [accessibility-modifier] get() = get-function-body and [accessibility-modifier] set parameter =

set-function-body

Properties may be declared static, in which case they are defined on the type itself and are limited to accessing other static members. We can also employ access specifiers to limit their visibility, although they are public by default. In this next example, we add a ReleaseDate property to the Movie class. This property exhibits both a get accessor for reading the value and a set accessor for setting the value.
open System \\provides access to DateTime type type Movie(title: string, released: DateTime) = let mutable _releaseDate = released member this.ReleaseDate with get() = _releaseDate and set(newValue) = _releaseDate <- newValue

As you can see here, we've defined a self-identifier called this via theas this following the type declaration. There are a few things to note about this example: To implement a property, we generally create a private backing field - a field that holds the value that the property manages. Here, our backing field is called _releaseDate. By convention, I like to use an underscore in my backing field definitions. F# imposes no such restrictions. Properties that implement a set member use a mutable backing; otherwise, callers won't be able to change its value. Properties are defined using a with and optional and keyword. We will discuss the specifics of these shortly. The setter receives a parameter that represents the new value of the property. To show how everything fits together, let's look at the following example:
open System type Movie(title: string, released: DateTime) = let mutable _releaseDate = released member this.ReleaseDate with get() = _releaseDate and set(newValue) = _releaseDate <- newValue let mv = new Movie("Paranormal Activity", new DateTime(2010, 10, 1)) printfn "The movie will be released %A" mv.ReleaseDate printfn "Oops..." mv.ReleaseDate <- new DateTime(2009, 10, 1) printfn "Correction...the movie will be released %A" mv.ReleaseDate

As you can see in the example, we use the destructive assignment operator (<-) to update the property value. Under the covers, F# translates this to a call to the property's set function. Properties are not required to have both getters and setters. You can implement a read-only property by defining get only, a write-only property by defining a set only. You can also include access specifiers to limit the property's availability, e.g., using internal to limit access to those classes in the same assembly or module. In the following example, we define a read-only property by implementing a get only. We simply do not provide a set. The syntax is quite straightforward, as shown here:
type Movie(title: string, released: DateTime) = let mutable _releaseDate = released member this.ReleaseDate \\read only using a solo get() with get() = _releaseDate

We can do the same thing to create a write-only property, although this is rarely done in practice:
type Movie(title: string, released: DateTime) = let mutable _releaseDate = released member this.ReleaseDate with set(newValue) = _releaseDate <- newValue

Like other values, properties can be type-annotated via an explicit type declaration. In the following example, the property TicketPrice is declared as decimal via the getter member:
type Movie(title: string, price : decimal) = let mutable _ticketPrice = price member this.TicketPrice with get() : decimal = _ticketPrice and set(newValue) = _ticketPrice <- newValue

Note that the get and set functions are not considered methods per se. They are considered functions that are used to implement property members. They are accessed indirectly via the property itself and are not directly exposed outside of the property's

context. In addition to classes, properties can be members of structures, discriminated unions, records, interfaces, and type extensions (to be discussed later) and can also be defined in object expressions (also to be discussed later). In addition, properties can be declared abstract. We will cover abstract constructs later in this chapter, when we discuss inheritance.

Combining Static and Instance Properties


There are several instances OOP when you want the class to keep track of the instances with which it is associated, e.g., keeping a count of the number of instances, limiting the creation of instances to a certain number or range, etc. The following example shows how to accomplish this in F# via static members. We've updated the Movie class to keep track of the number of Movies currently playing in theaters:
type Movie(title: string) = static let mutable numInTheaters = 0 do numInTheaters <- numInTheaters + 1 do printfn "Current count of movies in theaters = %d" numInTheaters let m1 = new Movie("Paranormal Activity") let m2 = new Movie("The Surrogates") let m3 = new Movie("Toy Story 3")

Recall that static let and static do bindings are executed once per type, while the non-static bindings are executed each time an instance is created. The results of running the code are:
Current count of movies in theaters = 1 Current count of movies in theaters = 2 Current count of movies in theaters = 3

Indexed Properties
There are times when you want to store collections of items in a property, and provide indexed access to the information. F# supports indexed properties just for this purpose. They take the following form:
member self-identifier.PropertyName with get(index-variable) = get-function-body and set index-variables value-variables = set-function-body

As you can see, an indexed property takes an index variable as a parameter. It's the property's job to map the index to an appropriate piece of data. To demonstrate how indexed properties work, let's add a list of actors to our Movie class:
type Movie(title, actors: string[]) = do printf "%s..." title let mutable _actors = actors member this.Actors with get(index) = if index < _actors.Length then _actors.[index] else "Unknown actor. Check the index." and set index value = if index < _actors.Length then _actors.[index] <- value let m = new Movie("The Hangover", [| "Bradley Cooper"; "Ed Helms"; "Zach Galifianakis"; "Justin Bartha" |]) let star = m.Actors(0) printfn "the star of the movie is %s" star

Indexed Properties with Item


Now, although the above example works, it really doesn't capture the spirit of indexed properties. The client is still calling accessing a distinct property and passing an index. If we want to make the object instance look like a collection of things, we can use the specially-named property Item. When we do this with indexed properties, F# provides some syntactic sugar, enabling us to access the instance as if it were a collection. Here is a new version of the Movie class that uses the specially-named Item property. I have removed the error checking to simplify the example:
type Movie(title: string, actors: string[]) = let mutable _actors = actors member this.Item \\<<< specially-named property with get(index) = _actors.[index] and set index value = _actors.[index] <- value let m = new Movie("The Hangover", [| "Bradley Cooper"; "Ed Helms"; "Zach Galifianakis"; "Justin Bartha" |]) let star = m.[0] \\<<< now we can use the instance like a collection printfn "The star of the movie is %s" star

When we access m.[0], behind the scenes, F# translates this into a call to m.Item.get(0). This syntax sugaring enables clients to

treat instances like indexed collections.

Indexed Properties with Multiple Indices


Indexed properties can have more than one index variable. This is useful when dealing with 2D arrays and other matrix-like structures. For example, if we build a 2D array that contains a multiplication table (think back to 4th or 5th grade), we can access the product of two numbers simply by accessing the intersection of the row and column specified by the numbers we're multiplying. We can combine this with the specially-named property Item as well, as in the following example:
type MTable() = let _table = Array2D.zeroCreate<int> 12 12 do for x = 1 to 12 do for y = 1 to 12 do _table.[x - 1, y - 1] <- x * y member this.Item with get(a, b) = _table.[a - 1, b - 1] let m = new MTable() let product = m.[3, 7]

From the F# Interactive Console: val product : int = 21

Methods
A method is a function, a.k.a., a behavior, that is associated with a class. In OOP, methods are the primary mechanism used to expose functionality and behaviors of objects and types. Methods may be instance methods, virtual instance methods, static methods, or abstract methods. In this section, we will cover static and instance methods. We will cover virtual and abstract methods once we've covered the F# inheritance model.

Static methods
Static methods are those that are defined using the keyword static, which binds the method to the type itself vs. instances of the type. In other words, all instances of the type share the type's static method. Static methods can access static members, and are callable only through the type itself. To define a static method, we use the following syntax:
[ attributes ] static member [inline] method-name parameter-list [ : return-type ] = method-body static methods are useful when proper execution is independent of the state of a given instance, i.e., when instance state does not affect the outcome. Many mathematical members, e.g., square root functions, etc., are implemented like this. In the follow example, let's write a DistanceConverter type that converts between miles and kilometers to illustrate the idea: \\1 kilometer = 0.621371192 miles, 1 miles = 1.609344 kilometers type DistanceConverter() = static member KilometersToMiles k: float = k * 0.621 static member MilesToKilometers m: float = m * 1.609 let x = DistanceConverter.KilometersToMiles 10.0 let y = DistanceConverter.MilesToKilometers 8.0

Notice that static methods do not include a self-identifer we use member KilometersToMiles instead of member this.KilometersToMiles. static members, by their nature, do not accept self-identifiers, since they are not associated with any instance. In contrast to static methods, we have instance methods, discussed next.

Instance Methods
Instance methods are those that are associated with each instance of the class. Instance methods take into account object state, and may change it during the course of execution. They are the "standard" methods for objects. In F#, we define instance methods using the following syntax:
[ attributes ] member [inline] self-identifier.method-name parameter-list [ : return-type ]= method-body

The two main differences in this syntax vs. static methods are: the absence of the static keyword and the introduction of a selfidentifier. Let's create an updated Movie class that implements a single instance method, CalcTicketPrice.
type Movie(title: string) = member this.CalcTicketPrice = if title.ToLower() = "jaws" then 7.50 \\old movie else 10.25 \\more like today's prices let m1, m2 = new Movie("The Hangover"), new Movie("Jaws") let p1, p2 = m1.CalcTicketPrice, m2.CalcTicketPrice

Overloaded Methods
F# types also support overloaded methods. A type defines overloaded methods when it declares two or more methods with the same name but taking a different number of arguments or the same number of arguments of differing types. In F# we tend to use optional arguments instead of overloaded methods; however, overload methods can provide a convenient

way to create methods that take completely different arguments. Let's look at a few examples:
type Movie(title: string, director: string, zip: string) = member this.Find(t, d) = if title = t && director = d then printfn "Movie found by title and director" else printfn "Cannot find movie by title and director" member this.Find(z) = if zip = z then printfn "Movie found by zip code" else printfn "Cannot find movie by zip code" let m = new Movie("Paranormal Activity", "Oren Peli", "01776") m.Find("Paranormal Activity", "Joe Smith") m.Find("Paranormal Activity", "Oren Peli") m.Find("01776")

Overloaded methods can have the same number of parameters, so long as at least one is of a different type; however, due to the fact that F# can curry functions, we generally want to specify our argument list in tupled form:
\\Define a class with overloaded methods type Foo() = member this.bar(x: int) = () member this.bar(x: string) = () member this.bar x = () member this.bar(x: int, y: string) = () member this.bar(x: int, y: float) = () \\Call overloaded methods let f = new Foo() f.bar(1) f.bar("s") f.bar 100M f.bar(100, "s") f.bar(200, 2.34) f.bar "true"

You can define as many overloaded methods on your classes as you need to.

Events
An event is a messages that one object sends to one or more other objects. An event signals that "something happened." When an object sends an events, we say that the object "fired the event" or "raised the event." The object that fires the event is called the event sender or the event source. The object receiving the event is called the event target, event sink or listener. Listeners implement event handler functions that are called in response to an event being fired. Events are characterized as distinct from properties and methods in that clients do not call event members. Instead, clients register interest in events that might eventually be raised by an event sender. With event communication, senders are disconnected from listeners. The sender does not know which object or method will receive the events it raises. To accommodate this "publish and subscribe" model of programming, there needs to be a broker between the sender and its receiver(s). Under the covers, .NET uses the delegate mechanism for this purpose.

Creating Delegates to Be Used with Events


For the purposes of discussing events, we can briefly describe delegates here[4]. In F#, we use the following syntax to define delegates:
type delegate-type = delegate of type -> type

The delegate type you create is designed to wrap, i.e., call, a function of the same type. For example, if we have a function that accepts an integer value and returns a float, e.g.:
let f n = float n / 2.0

We can create a delegate type that can call this function:


type FDelegateType = delegate of int -> float

To call a function through a delegate, we need to create a new instance of the delegate and "wrap" the target function, e.g.:
let fd = new FDelegateType(f)

To call the function through the delegate, we use the delegate's Invoke method:
let result = fd.Invoke(10)

Of course, we can use delegates to wrap lambda functions as well. We could have written the above example as:
type FDelegateType = delegate of int -> float let fd = new FDelegateType(fun n -> float n / 2.0) let result = fd.Invoke(10)

Creating Events
To create an event, you use the new Event<'delegate, 'argument> construct. This creates and returns an event object that senders can subsequently fire. The first parameter to the Event constructor is a delegate type that defines the listener function. The second parameter is the type of argument the event sends along when it's fired, i.e., information attached to the event sent to the listener function. When creating delegates to be used with events, we're expected to follow certain conventions. First, our event delegates are expected to take two parameters the source, i.e., the object raising the event, which must be specified as type obj, and the event argument. The event argument can be of any type; however, it's mostly either a simple type, e.g., string, or an object derived from System.EventArgs. The event delegate is expected to return unit. In the following example, we create a StockAlerter class that implements an event indicating when a given stock should be sold. The first thing we'll do is create the delegate type, based on the rules defined above:
\\Event delegate. Follows expected delegate conventions: obj * args -> unit. type StockAlertDelegate = delegate of obj * string -> unit

This delegate type tells us that the listener function accepts two parameters: the sender, which must be specified as type obj, and the event argument. Here, we are choosing to pass a simple string. We can use this delegate and argument to implement create an appropriate Event instance in the StockAlerter class:
\\Event source. Raises StockAlert events. type StockAlerter(symbol: string) = do printfn "Watching %s" symbol let alertEvent = new Event<StockAlertDelegate, StockAlertEventArgs>()

After defining an event, we need a way for clients, a.k.a. subscribers, to register interest in the event. To make our events visible to clients and eligible for subscription, we need to publish the event. We do this via a public member of the class and the Publish method of the event class:
member this.StockAlertEvent = alertEvent.Publish

Clients access the alert event via the public member StockAlertEvent. The only thing missing is a way to actually fire the event. Generally speaking, the event source implements some internal algorithm that results in it firing an event, e.g., it might check the value of a stock every five minutes and fire an event if the price changes by some specified percentage. For our purposes, we'll create a function that fires the event whenever it's called. The entire StockAlerter class is shown below:
\\Event source. Raises StockAlert events. type StockAlerter(symbol: string) = do printfn "Watching %s" symbol let alertEvent = new Event<StockAlertDelegate, string>() member this.StockAlertEvent = alertEvent.Publish \\Fire event. this=sender=StockAlerter instance, formatted string is argument \\passed to client handler function. member this.SellStock() = alertEvent.Trigger(this, sprintf "sell %s!" symbol)

When we define events that need to carry extra information to their handlers, we implement a class that derives from System.EventArgs, e.g.:
\\Event argument. Carries information about the event. type StockAlertEventArgs() = inherit System.EventArgs() member this.message = "Time to sell!"

We then use the class type as the second parameter to the delegate definition:
\\Event delegate. Follows expected delegate convention: obj * args -> unit. type StockAlertDelegate = delegate of obj * StockAlertEventArgs -> unit

Whenever our code fires an event, it needs to pass along the sender and an instance of the appropriate event argument.

Listening for Events


Events are useless unless something is listening for them to occur. To continue our stock alerting example, let's create a StockBroker class that implements an event listener:
\\Event sink. type StockBroker() = \\Create a StockAlerter let sa = new StockAlerter("MSFT") \\Create an event listener via creating the appropriate delegate let eventListener = new StockAlertDelegate( fun sender msg -> printfn "%A tells us to: %s" sender msg) do

\\Add listener to event's list of listeners sa.StockAlertEvent.AddHandler(eventListener) \\Cause event to fire. Normally, the StockAlerter would fire its \\own event independtly. We're doing this here to demonstrate \\the mechanism. sa.SellStock()

To add a listener function, we access the source event, e.g., sa.StockAlertEvent, and call it's AddHandler method. AddHandler adds the given delegate to the event's internal list of listeners. When the event fires, the underlying event class iterates over its list of listeners and calls each one in turn via the stored delegate. When a client no longer cares to receive events from a source, it need to unregister its interest in the given event. To unregister interest in an event, the client can call the event's RemoveHandler method, as shown:
type StockBroker() = \\ \\Unregister sa.StockAlertEvent.RemoveHandler(eventListener) \\Nothing printed now since we're not listening anymore sa.SellStock()

Since the Event class maintains an internal list of delegates to the client handler functions, we want to unregister handlers whenever the client handlers go out of scope, or whenever we no longer need an active event connection. If we are not careful about disconnecting our event listeners from our event sources, we can end up crashing the application, since the event source may try to call a listener function that no longer exists.

Observable Events
As of the latest release, F# events are first-class citizens that implement the IObservable interface. From Don Syme's blog on the CTP 1.9.7.8 release (http://blogs.msdn.com/dsyme/archive/2009/10/19/release-notes-for-the-f-october-2009-release.aspx) :

The IObservable and IObserver interfaces provide a general interface over observable data, which can be easily composed. These interfaces are provided in .NET4.0, and are available in F# for .NET2.0. 1st class events in F# now implement the IObservable interface, enabling them to interoperate with other IObservable programming models. A new Observable module in the F# library provides compositional functions for manipulating general Observable data:
Observable.merge Observable.map Observable.filter Observable.partition Observable.split Observable.choose Observable.scan Observable.add Observable.subscribe

What this means to us is that we can use the Observable module to work with events in a functional manner. For example, let's suppose we want to limit the stock events we care about to those whose associated stock symbols are 3 characters exactly. We can use the Observable.filter method to do just this:
\\Event delegate. type StockAlertDelegate = delegate of obj * string -> unit \\Event source. Raises StockAlert events. type StockAlerter(symbol: string) = do printfn "Watching %s" symbol let alertEvent = new Event<StockAlertDelegate, string>() member this.SellStock() = alertEvent.Trigger(this, symbol) [<CLIEvent>] \\<<< .NET and Observable friendly member this.StockAlertEvent = alertEvent.Publish \\Event sink. type StockBroker(sa: StockAlerter) = \\Create an event listener via creating the appropriate delegate let eventListener = new StockAlertDelegate( fun sender msg -> printfn "%A tells us to: %s" sender msg) let filteredEvent = sa.StockAlertEvent |> Observable.filter(fun (sym: string) -> sym.Length = 3) \\only watch symbols with 3 letters |> Observable.add(fun msg -> printfn "Filtered event: SELL %s" msg) \\hook up event handler do sa.SellStock()

\\We expect to see an IBM message. We do not expect to see a MSFT message. let saIBM, saMSFT = new StockAlerter("IBM"), new StockAlerter("MSFT") let sbIBM, sbMSFT = new StockBroker(saIBM), new StockBroker(saMSFT)

In order to work with events via the Observable module, the events must be marked with the [<CLIEvent>] attribute, making them .NET-friendly. Additionally, to hook up a listener to an Observable, use the Observable.add method, as demonstrated above. Please consult the MSDN documentation for the fully skinny on Observable. (http://msdn.microsoft.com/en-us/library/ee370313(VS.100).aspx)

ignore
To be honest, I wasn't sure where to discuss the ignore keyword, so I thought it would be somewhat appropriate here, in the section in events and event processing. To tell F# that you want to ignore the result of an expression and always return unit, you can use ignore. This can be helpful to ignore events (thus its introduction here), return unit where the normal flow of code returns a non-unit, etc. Here are some examples of using ignore:
let test = ignore 10 \\test = unit \\return type is now in line with expectations

System.Console.ReadKey() |> ignore

Use ignore when you want to return unit wherever it's expected. For example, if you fail to use |> ignore in the example above, F# will warn you that "The expression should have type 'unit', but has type 'System.ConsoleKeyInfo'."

Specifying Generic Class Types


When defining a class, you can specify that it accepts one or more type parameters, much like the built-in collection classes do. For example, if we wan to implement a class that compares two objects of the same type, we could specify the class as follows:
type MyComparer<'a>() = member this.Compare(x: 'a, y: 'a, f) = f x y

As you can see, we specify generic type parameters in angle brackets(<>) as part of the type declaration. In this example, using generics helps to express and enforce the intent of comparing only objects of the same type. In this implementation, we supply the elements to compare as well as a comparison function that is subsequently applied. Note that there is an alterate syntax for specifying generic parameters, where the generic parameters are specified before the type name. To rewrite the MyComparer type using this alternate syntax, we would write it as follows:
type 'a MyComparer() = member this.Compare(x: 'a, y: 'a, f) = f x y

In general, I prefer the angle-bracket syntax; however, you will see both in this book and in other F# code.

Wildcard as Type Argument


When building a generic type or function, you can instruct the compiler to infer the type argument by using the wildcard symbol (_), instead of a named type argument. This is shown in the following code.
let printSequence (s: seq<_>) = Seq.iter (fun elem -> printf "%s " (elem.ToString())) s

This form is generally reserved for cases when the code does not reference the type argument, as in this example. We could just as easily have written the example this way:
let printSequence2 (s: seq<'a>) = Seq.iter (fun elem -> printf "%s " (elem.ToString())) s

And it would have worked identically.

Generic Type Constraints


When dealing with generic types, there are times when you may want to restrict or constrain the types that can be used. F# supports the following flavors of constraints: type constraints, null constraints, explicit member constraints, constructor constraints, value type constraints, reference type constraints, enumeration type constraints and delegate constraints. These are summarized in the MSDN documentation found here. (http://msdn.microsoft.com/en-us/library/dd233203(VS.100).aspx) We need to use genetic type constraints when our code requires a feature that is available on the constraied type but is not guaranteed to be available on a generic type. For example, if our code depends on the generic type to implement a particular interface, e.g.., IComparable, we can constain the generic type argument to accept only those classes that implement the IComparable interface. Let's take a look at a few of the most often used constraints and provide an example of their use.

Type Constraints
Type constraints are the most often used of the constraint family. A type constraint limits the provided generic arguments to be

equal to or derived from the type specified. It is also used to constrain the provided type argument to a type that implement a given interface. In the following example, the generic type argument is limited to those types that implement the ILoveProgramming interface (we discuss interfaces later in this chapter):
type ILoveProgramming = abstract Program: unit -> unit type Programmer<'a when 'a :> ILoveProgramming>() = do printfn "I am a programmer who loves to program!"

Note the use of the symbol ( :> ). Among other things, it is used in the type constraint syntax to specify the type to which the generic must conform. For fine-granied control over generic type arguments, we can combine constraints. In the following example, we can only construct instances of the MyCollection via by supplying arguments that are Stacks (found in System.Collections) implementing the IDisposable interface:
open System open System.Collections type MyCollection<'a when 'a :> IDisposable and 'a :> Stack>() = do printfn "We only accept disposable stacks here, my friend."

Of course, if your type accepts multple type arguments, you can constrain each of them individually, as in the folllowing example:
open System.Collections open System.Collections.Generic type MyCollection<'a, 'b when 'a :> IEnumerable<'a> and 'b :> ArrayList>() = do printfn "'a must implement IEnumerable, 'b must be an ArrayList of some sort."

Constructor Constraints
The constructor constraint is used to ensure that the provided type has a public, default constructor. A default constructor is one that takes no arguments. I guess a more accurate name for this constraint is the "public default constructor constraint." It's possible that a .NET class not implement a a public, default constructor. This happens when the class author has implemented a public constructor that takes parameters. In these cases, the compiler does not generate a default constructor. The constructor constraint provdes useful when creating collections of objects, where the absence of a default constructor can cause problems. In the following example, the generic argument that we use to create MyCollection must implement a public, default constructor:
type MyCollection<'a when 'a: (new : unit -> 'a)>() = do printfn "default constructor constraint applied"

The other type constraints adhere a similar syntax and usage pattern.

Mutually ReadKeycursive Class Definitions


If you need to define types that reference each other and create a circular dependency, you need to string together the type definitions by using the and keyword. The and keyword replaces the type keyword on all except the first definition, as shown here:
type [access-modifier] type-name1 ... and [access-modifier] type-name2 ...

In the following example, we define two classes, Student and University, each needing to know about the other.
type Student(ssn: string, u: University) = let _ssn, _u = ssn, u and University() = member this.EnrollStudent(s: Student) = ()

General Form
As a summary, here is the general from of a class:
type [access-modifier] type-name [type-params]( parameter-list ) [ as identifier ] = [ class ] [ inherit base-type-name(base-constructor-args) ] [ let-bindings ] [ do-bindings ] member-list ... [ end ]

Here is a quick run-down on the class declaration's piece-parts:

declarations, abstract bindings, and property and event declarations. as identifier provides a local alias that the class itself can use in its definition a "self identifier" akin to the this keyword in C++ and C#. end optional keyword that marks the end of the class body. Pairs up with the optional class keyword.

type keyword that introduces a new type. We've seen this before with records, etc. access-modifier public, internal or private. type-name the class name. type-params used when you want to add generic type parameters to be used in the class, e.g., <'a>. parameter-list used to create instances of the class (what you pass to the constructor). class optional keyword introducing the class body. Pairs up with the optional end keyword. inherit used to specific this class's base class, if any. let-bindings enables us to declare fields and function values that are local to the class. do-bindings includes code to be executed when the an object of the class is constructed. member-list contains constructors, static method declarations , instance method declarations, interface

Adding Constructors and Member Functions to Aggregate Types


Now that we've discussed classes and their component parts, let's briefly revisit the aggregate types and demonstrate how to add members, e.g., properties and methods, to them.

Structures
As discussed earlier in this chapter, structures, like classes, can have a primary constructor, and you can provide additional constructors by using keyword new. Note that structures always have a default constructor (that is, one with no arguments) generated by F#. The default constructor initializes all the fields to the default value for that type, zero for numeric types and null for object types. Any constructors that you define for structures must have at least one argument so that they do not conflict with the default constructor that F# generates for you. Structures can also include members such a properties, methods and events, as shown below (sans events, for brevity).
[<Struct>] type Movie = val Title: string val Director: string val ReleaseYear: int new(t, d, y ) = { Title = t; Director = d; ReleaseYear = y} member this.Marquee with get() = "*** " + this.Title + " by " + this.Director + " released " + string this.ReleaseYear + " ***" member this.CalcTicketPrice() = if this.ReleaseYear >= 2009 then 11.00 else 9.00 let mv = new Movie("Where the Wild Things Are", "Jonze", 2009) printfn "%s" mv.Marquee let p = mv.CalcTicketPrice() printfn "That'll be $%2.2f, please!" p

Discriminated Unions
Although discriminated unions do not support constructors per se, individual discriminators can accept initialization parameters. In addition discriminated unions can include other members, e.g., properties, methods, and events. In the following example, we define a discriminated union Shape that includes a method Draw:
type Shape = | Circle of double | Triangle of double * double * double | Square of double member this.Draw() = match this with | Circle(x) -> printfn "Drawing circle of radius %f" x | Triangle(x,y,z) -> printfn "Drawing triangle with sides %f %f %f" x y z | Square(x) -> printfn "Drawing a square with diagonal %f" x let c, t = Circle(10.0), Triangle(3.0, 4.0, 5.0) c.Draw(), t.Draw()

Records
Similar to discriminated unions, records do not support constructors explicitly, but employ the creation semantics as discussed previously. Records also support properties and methods. Records are different from classes in that their fields are automatically exposed as properties. Let's define a Student record that demonstrates these capabilities:
type Student = {

} member this.GraduationYear with get() = this.YearEntered + 4 member this.UpdateGPA(newGPA: float) = this.GPA <- newGPA let s = { Name="Jim Kress"; YearEntered=2008; GPA=3.1 } s.UpdateGPA 3.8 printfn "%s will graduate in %d with a %f GPA" s.Name s.GraduationYear s.GPA

Name: string; YearEntered: int; mutable GPA: float;

When to Use Classes, Unions, Records, and Structures


Given the variety of types to choose from, it can be hard to know which ones to address a given problem or scenario. The following rules of thumb are adapted from the MSDN documentation (http://msdn.microsoft.com/enus/library/dd233205(VS.100,printer).aspx) : Classes are the lingua franca of OOP, and are used heavily throughout the .NET framework. If your application is objectoriented, or needs to interact closely with other .NET components written in C#, VB. NET, etc., classes are a good choice. If you are not interoperating closely with OO code, you should consider using records and discriminated unions. A discriminated union, together with appropriate pattern matching code, can often be used as a simpler alternative to an object hierarchy. Records have the advantage of being simpler than classes, but records are not appropriate when the demands of a type exceed what can be accomplished with their simplicity. Records are basically simple aggregates of values that can perform custom actions. They do not contain private fields, and cannot participate in inheritance or interface implementations. Although members such as properties and methods can be added to records to make their behavior more complex, the fields stored in a record are still a simple aggregate of values. Structures are also useful for small aggregates of data, but they differ from classes and records in that they are .NET value types. Classes and records are .NET reference types. Therefore, structures are appropriate for frequently accessed data when the overhead of accessing the heap is a concern.

What You Need to Know


F# supports a full complement of OO technologies include structures, classes, interfaces, inheritance, etc. Structures in F# are stack-based value types that enable you to logically and semantically group related data. Structures can have implicit or explicit constructors, immutable fields, and mutable fields. You use the [<Struct>] attribute to declare a structure. To create fields, you use the val keyword. You create instances of structures using the new keyword. Fields marked as mutable are modified via a mutable structure instance. F# supports the access specifiers public, internal and private. protected is listed as a reserved keyword for the future. F# supports classes. You use the type keyword to define them. Classes support the standard OO structures of constructors, overloaded constructors, properties, methods, events, interfaces, statics, etc. F# does not have a specific keyword for identifying object instances you can define your own. Many people tend to use this based on past experience. You create instances of classes via the new keyword (new is optional). Many people tend to use new because it's explicit and clear. You can use generic parameters when defining classes. You can specify them in one of two ways: type 'a MyClass() or type MyClass<'a>. Generic type can be constrained, e.g., to being inherited from a given ancestry using the :> operator. F# supports flexible types, which constrain a type to a given hierarchy. The syntax is #type. You see flexible types used often in conjunction with the Seq type to accommodate different IEnumerables. In addition to classes, you can add constructors and members to aggregate types such as structures, unions and records.
[1]There

is also a syntax used when #light is not being used. As mentioned earlier, we are eschewing the heavy syntax in this text. Please see the MSDN documentation (http://msdn.microsoft.com/en-us/library/dd233233(VS.100).aspx) for details on the other syntax option. [2]In some older documentation, you will see that the let keyword can include an "and" conjunction. This is for compatibility with OCaml, and is deprecated as of this writing. [3]Although, you can create a public property that accesses the field. [4]We cover them more fully in the next chapter.

Chapter 14 Object-Oriented Programming, Part II


Introduction
Now that we understand class fundamentals, we're in a position to explore F#'s support for more advanced OOP concepts such as inheritance and type extensions. We begin by discussing how F# implements inheritance, which leads us steadily into a lively discussion about abstract classes and interfaces. We then discuss casting, type conversions, and type extensions. We conclude this chapter with a brief discussion of attribute classes.

Inheritance
Some of the power and elegance (and problems!) of OOP comes in the form of inheritance the ability to base a new type on the structure and function of a previously defined type. While the philosophies governing the proper use of inheritance are beyond the scope of this book, how to implement inheritance in F# is squarely within our purview. To create a new type that is based on an existing type, we use the inherit keyword. In the following example, we create a class called MyEncryptedFile that is based on an MyFile:.
type MyFile(name: string) = do () type MyEncryptedFile(ename: string) = inherit MyFile(ename) \\base constructor requires args, so pass do ()

A class can have at most one direct base class, although it can have a long line of ancestors. If a class does not inherit from another class explicitly, it implicitly inherits from .NET's ultimate base class, Object. In F# the Object class is represented by the obj keyword. You can represent any object via obj, as in the following example:
let o = new obj(); printfn "%s" (o.ToString())

Note that F# also supports the keyword null to indicate the absense of an object. When a derived class inherits from a base class, all of the non-private members of the base class are available to users of the derived class automatically. If the derived class needs to access a member of the base directly, it uses the base keyword. Let's flesh out our HttpManager example to demonstrate these mechanisms in action:
type MyFile(name: string) = member this.Create() = printfn "MyFile created" member this.Close() = () type MyEncryptedFile(ename: string) = inherit MyFile(ename) member this.Create() = base.Create() printfn "MyEncryptedFile created" \\base constructor requires args, so pass \\create file using base implementation \\custom work here

Notice that when the base class constructor expects an argument (as our MyFile class does), the derived class needs to pass the argument this along as part of the inheritance declaration construct.

Overrides
There are many times in OOP where a derived class re-implements a method defined in one of its base classes (more than one coming from its inheritance chain, not from multiple parents). If a derived class implements a member function with the same name, number and type of parameters as that of it base class, the derived class masks or hides the base's implementation. Let's look at an example:
type MyFile(name: string) = member this.Create() = printfn "MyFile created" member this.Close() = () type MyEncryptedFile(ename: string) = inherit MyFile(ename) \\hides base implementation member this.Create() = printfn "MyEncryptedFile created"

In this example, the MyEncryptedFile's Create method overrides MyFile's implementation. There's nothing too crazy about this things works you'd expect. If you create a MyFile instance and call its Create method, "MyFile created" will be printed. If you create a MyEncryptedFile instance and call its Create method, "MyEncryptedFile created" will be printed. So far, so good. The wrinkle happens when we have a base class object that actually refers to a derived class, i.e., a MyFile that refers to a MyEncryptedFile. Given the definition of the MyFile and MyEncryptedFile classes above, let's demonstrate what we mean:
let mutable mf = new MyFile("foo") mf.Create() let mef = new MyEncryptedFile("bar") mef.Create() mf <- mef \\base class now holds derived class mf.Create() \\what's printed?

In order for F# to call the correct method based on the actual type of the object being referenced, we must make the Create method virtual. Let's see how to do that now.

Abstract & Virtual Methods


A virtual method is one that participates in dynamic dispatch. Dynamic dispatch enables us to declare an instance of a base class, assign into it an instance of a derived class, and have the correct method called when we call an overridden method through the base reference. Instead of hiding the base method, the derived class can override it. To tell F# that a method is override-able and should participate in dynamic dispatch, we make the base member virtual by using the abstract keyword. We use the keyword abstract regardless of whether or not the base class supplies an implementation (this is different from other OO languages like C#). To demonstrate the idea, let's change the definitions of our file classes a bit:
type MyFile(name: string) = abstract member Create: unit -> unit default this.Create() = printfn "MyFile created" member this.Close() = () type MyEncryptedFile(ename: string) = inherit MyFile(ename) \\overrides base implementation override this.Create() = printfn "MyEncryptedFile created"

Things to notice about this example: The syntax for declaring an abstract member is:
abstract member member-name : type Here, Create is a method that accepts

no arguments (unit) and returns nothing (unit). To provide a default implementation for an abstract (a.k.a., virtual) member in the base class, we use the following syntax: In the derived class, we have the option of supplying our own implementation. To do this, we use the following syntax:
override self-identifier.member-name arguments = member-body default self-identifier.member-name arguments = member-body

If we omit the default implementation in the base class, the entire base class becomes abstract, which means you cannot instantiate an instance of the type. This means that if a developer wants to implement the functionality defined in the base class, he must do so via creating a derived class and implementing all the abstract methods defined in the base. Additionally, if the derived class chooses not to override the existing base implementation, it uses the implementation defined in the base class. If we now re-run the sample, we get a different (and more accurate) result:
let mutable mf = new MyFile("foo") mf.Create() let mef = new MyEncryptedFile("bar") mef.Create() mf <- mef \\base class now holds derived class mf.Create() \\what's printed?

Abstract Classes
Abstract classes are ones that leave some or all members unimplemented, so that derived classes can provide implementations. In F#, we define abstract classes using the following syntax:
[<AbstractClass>] type [ accessibility-modifier ] abstract-class-name = [ inherit base-class-or-interface-name ] [ abstract-member-declarations-and-member-definitions ] // Abstract member syntax. abstract member member-name : type-signature

Abstract classes represent common protocol and functionality for a family of related classes. They are useful for defining what a family of classes needs to do, and may supply some default implementations for one or more of their members. Derived classes can override default implementations. We saw a glimpse of this in the previous example. A class is considered abstract only if there are abstract methods that are declared but not defined (have no default implementations). Only use the AbstractClass attribute when your class has undefined abstract methods. In the following example, we define an abstract class Clock that serves as the template for a family of different clock types. We also define two derived classes that represent a 12-hour and a 24-hour clock respectively:
[<AbstractClass>] type Clock(dt: System.DateTime) = member internal this._dt = dt abstract GetTime : unit -> string default this.GetTime() = dt.ToString() abstract RingAlarm: int -> unit type Clock12() = inherit Clock(System.DateTime.Now) override this.RingAlarm(vol) = printfn "(Volume at %d) Ring, ring, ring..." vol type Clock24() = inherit Clock(System.DateTime.Now) override this.RingAlarm(vol) = printfn "(Volume at %d) Buzzzzzzzzzzzzzz" vol override this.GetTime() = base._dt.ToString("HH:MM")

In this example, we see the AbstractClass attribute applied properly, using internal members to support enapsulation, using a default member to support a default implementation, overriding a default member, and leveraging the base keyword. Note that abstract classes themselves may inherit from other abstract classes. The entire chain of classes is considered to be abstract and is terminated only by a concrete class, i.e., one that implements the specificed class protocols in their entirety.

Interfaces
Like abstract classes, interfaces define a set of behaviors. The fundamental difference between abstract classes and interfaces is that interface members do not (cannot) define any implementation[1] they are pure protocol that classes or object expressions (covered later in this chapter) can choose implement.

Defining Interfaces
We define an interface using the following syntax:
// Interface declaration [ attributes ] type interface-name = [ interface ] abstract member1 : [ argument-types1 -> ] return-type1 abstract member2 : [ argument-types2 -> ] return-type ... [ end ]

Let's use this syntax to define an interface that is representative of a message in a messaging system, e.g., SMS or e-mail.
type IMessage abstract abstract abstract abstract = SetRecipient : string -> bool SetBody : string -> unit Attach : obj -> unit Send : unit -> bool

Note that with the #light syntax, the interfaceend construct (as shown in the general form) is optional. If you do not supply an interfaceend, the F# compiler will attempt to determine if the element being defined is a class or an interface based on context. If you run into ambiguous situations, you can always specify that you're creating an interface by using interfaceend semantics. Having defined this interface, we can write a class to implement it. Of course, more than one class can choose to implement a given interface.

Implementing Interfaces Using Classes


A class implements an interface using the following syntax:
// Implementing inside a class type definition interface interface-name with member self-identifier.member1 argument-list = method-body1 member self-identifier.member2 argument-list = method-body2

In the following example, we create a class that implements the IMessage interface defined above:

type EMailMessage() = interface IMessage with member this.SetRecipient recipient = true member this.SetBody body = () member this.Attach entity = () member this.Send() = true

Each class that implements this interface can provide its own implementation, completely independent of all other implementations. Classes can implement more than one interface, i.e., they are not restricted to a implementing a single interface. This enables classes to be behavior-compatible (and substitutable) without needing to be part of the same inheritance hierarchy[2]. Here is a short example:
type ILoveFSharp = interface \\just to show the syntax abstract Test: unit -> unit end type IRobot = abstract Activate: string -> bool type Robot() = interface IRobot with member this.Activate(name: string) = true interface ILoveFSharp with member this.Test() = printfn "test OK"

In this example, the Robot class implements the IRobot and ILoveFSharp interfaces.

Interfaces with Generic Parameters


You can define interfaces that accept generic type parameters. In the following example, we define a generic interface for working with basic collections.
type ICollection<'a> = abstract AddElement: 'a -> unit abstract RemoveElement: 'a -> bool abstract FindElement: 'a -> 'a

This interface accepts a type argument and uses this argument throughout its definition, as appropriate.

Interface Hierarchies
Interfaces can inherit from other interfaces, forming an interface hierarchy. This works for both non-generic and generic interfaces. This enables us to define an interface, use it as the basis of a specialized interface, ad infinitum. In the following example, we define a base interface called ICollection (which happens to be generic this is immaterial to the example). We then create a new interface, IList, that's based on (derived from) ICollection. Lastly, we create a class that implements IList, which means it needs to implement all the members of IList, which includes the members from ICollection plus the members defined within IList itself.
\\Interface with generic type parameter type ICollection<'a> = abstract AddElement: 'a -> unit abstract RemoveElement: 'a -> bool abstract FindElement: 'a -> 'a \\Interface inheritance (with generic types) type IList<'a> = inherit ICollection<'a> abstract Iterate: (unit -> 'a) -> unit \\Iterate takes a function that takes 0 arguments \\and returns an instance of an 'a. Iterate \\itself return nothing (unit). \\Concrete type that implements the IList interface using integers type IntList() = interface IList<int> with member this.AddElement(element) = () member this.RemoveElement(element) = true member this.FindElement(element) = 123 member this.Iterate f = ()

To call an interface member, you must do so via the interface itself having access to an object instance that implements the interface is not enough. This means that when you have an object instance and want to call one of its interface members, you need to cast. Luckily, that is the topic of the next section [3].

Casting and Conversions

I like the explanation of casting from the MSDN documentation:

Conversion between types in an object hierarchy is fundamental to OOP. There are two basic types of conversions: casting up (upcasting) and casting down (downcasting). Casting up a hierarchy means casting from a derived object reference to a base object reference. Such a cast is guaranteed to work as long as the base class is in the inheritance hierarchy of the derived class. Casting down a hierarchy, from a base object reference to a derived object reference, succeeds only if the object actually is an instance of the correct destination (derived) type or a type derived from the destination type.
Casting comes into play in various situations, e.g., when converting numeric types, etc. We now look at casting from the perspective of objects and OOP, referred to as upcasting and downcasting.

Upcasting
Upcasting is the process of casting a derived object to an instance of a base object or implemented interface. To upcast, you use the upcast operator (:>). Since you cannot call an interface member directly through an object instance, you use the :> operator to obtain a proper interface reference. Let's look at an example of calling the Send method defined in our previous IMessage example:
let email = new EMailMessage() let sentOK = (email :> IMessage).Send()

The :> operator performs a static cast, which means that the success of the cast is determined at compile time. If a cast that uses :> compiles successfully, it is a valid cast and has no chance of failure at run time. In F#, when you pass arguments to object methods, upcasting is applied automatically. For let-bound functions in a module[4], however, upcasting is not automatic. For let-bound functions in a module, you must use an explicit upcast, unless the parameter type is declared as a flexible type, which we discuss shortly. The upcast operator can cast to any base class, regardless of how "far up" it is in the hierarchy. In the following example, we create a hierarchy and demonstrate an upcast up several levels of the ancestry:
type GrandPa() = \\implied: inherit obj() member this.sayHello() = printfn "GrandPa says hello!" type Dad() = inherit GrandPa() member this.sayHi() = printfn "Dad says hi!" type Son() = inherit Dad() member this.sayGreetings() = printfn "Son says greetings!" type Junior() = inherit Son() member this.sayGoodMorning() = printfn "Junior says 'morning!" member this.sayHello() = printfn "Junior says hello!" let jr = new Junior() jr.sayHello() (jr :> GrandPa).sayHello()

Note that F# also supports an upcast keyword that uses the syntax upcast expression. F# tries to figure out, at compile time, the target of the upcast, i.e., what the expression should be upcast to. If it cannot figure out from context the target type, it reports a compile-time error.

Downcasting
The flip side of upcasting is, of course, downcasting. Downcasting is taking a base class object and casting it to an instance of a derived class. F# supports the downcast operator (:?>). The :?> operator performs a dynamic cast, which means that the success of the cast is determined at run time[5]. If the object is compatible with the target type, the cast succeeds. If the object is not compatible with the target type, the runtime raises an InvalidCastException. The question mark comprising the operator reminds us that the cast could fail, i.e., it is "questionable." Like its OO brethren from other languages, the downcasting operator behaves as you'd expect when downcasting a base class to a derived class. If the base class instance is the result of a derived class having been upcast, the downcast works, e.g.:
let d = new Dad() let g = (d :> GrandPa) let d2 = (g :?> Dad)

\\upcast \\related downcast works

On the other hand, if you attempt to cast a "pure" base class object (one not previously upcast) to a derived object, this results in an InvalidCastException, since F# cannot guarantee the fidelity of the cast, e.g.:
let g = new GrandPa() let d = (g :?> Dad) \\InvalidCastException

Due to the possible failure of the downcast operator, most F# code avoids it in favor of using the dynamic type checking operator, discussed next.

Pattern Matching and Dynamic Type Checking


Back in chapter 12, we discussed being able to pattern match on different data structures, and promised to revisit pattern matching with classes. Classes participate in pattern matching based not on their structure but on their types. To determine the type of an instance, you use the type checking operator ( :?). This operator is used in a match expression to test if a given instance is of a particualr type. To re-code the previous example using the :? operator, we would write the following:
let g = new GrandPa() match g with | :? Dad as gramps -> printfn "can downcast GrandPa to a Dad" | _ -> ()

Now, this does not alter the "castability" of g - the match returns unit and does not print anything, meaning that as far as F# is concerned, the g instance cannot be downcast to a Dad instance. If we again perform the upcast followed by the downcast, the operation will succeed, as shown below:
let g = (new Dad() :> GrandPa) match g with | :? Dad as daddyo -> printfn "can cast GrandPa to a Dad" daddyo.sayHi() | _ -> ()

Now the F# match expression "matches" and we get the "can downcast GrandPa to a Dad" and the "Dad says hi!" strings printed out to the F# Interactive Console. This type of downcasting and pattern matching (type checking for classes) works all the way up and down the inheritance hierarchy. This means, for example, that you can cast a grandchild class to a grandparent base and subsequently downcast the grandparent, and all the casts work correctly.

Flexible Types
Flexible types are just a fancy name for an additional flavor of type constraint. Flexible types enable us to specify that a method accepts as an argument a type or anything derived from that type. Given their purpose, I think the name is misleading they should really be called "flexible arguments." These "flexible arguments" are specified via the hash symbol (#). Why do we need flexible types? In most OO languages that support inheritance, there are situations where the language provides automatic upcasting base classes, derived classes and interfaces can be used together somewhat seamlessly. In F#, these conversions are applied automatically to member arguments; however, they are not applied to "global" functions arguments defined via let. Here is what the the MSDN documentation (http://msdn.microsoft.com/en-us/library/dd233220(VS.100).aspx) says relative to upcasting and flexible types:

In many object-oriented languages, upcasting is implicit; in F#, the rules are slightly different. Upcasting is applied automatically when you pass arguments to methods on an object type. However, for let-bound functions in a module, upcasting is not automatic, unless the parameter type is declared as a flexible type.

In F#, as in other object-oriented languages, there are contexts in which derived types or types that implement interfaces are automatically converted to a base type or interface type. These automatic conversions occur in direct arguments, but not when the type is in a subordinate position, as part of a more complex type such as a return type of a function type, or as a type argument. Thus, the flexible type notation is primarily useful when the type you are applying it to is part of a more complex type.
What this all means is that flexible types provide a way to declare functions that accept as arguments values of a particular OO ancestry or interface family. In other words, flexible types are used when we want to say "function arguments of this type and anything derived from this type" and we want to take advantage of transparent upcasts. Flexible types are useful specifically when the automatic conversion to types higher in the type hierarchy does not occur automatically, but you still want to enable your code to work with any type in the hierarchy or any type that implements an interface. In the F# library, we tend to see flexible types in the definition of Seq methods. For example, the Seq.append method boasts the following signature:
#seq<'a> -> #seq<'a> -> seq<'a>

Note that this signature does not define a new type it simply annotates an existing type to tell the compiler to accept any type in the specified hierarchy. In this particular example, since seq represents an IEnumerable, the Seq.append method accepts an IEnumerable or any interface or class implementing IEnumerable.

It is helpful to understand that a flexible type is equivalent to a generic type that has a type constraint (:>) applied. For example[6]:
open System.Windows.Forms let setTextOfControl (c: #Control) (s: string) = c.Text <- s \\is equivalent to let setTextOfControl2 (c: 'a when 'a :> Control) (s: string) = c.Text <- s

Boxing
An idea that goes hand-in-hand with casting and conversions is that of boxing and unboxing. Boxing is the process of wrapping an object around a value type, making it useful as a reference type (like putting the value type in a reference type "box"). Unboxing is the process of unwrapping the value type (taking it "out of the box.") This can be useful , for instance, when dealing with legacy containers that do not support generic type specifications. The following example shows an example of boxing and unboxing:
let myInt = box 100 let i : int = unbox myInt

Using boxing and unboxing, you can store value types in collections and other data structures that accept object (obj in F#) parameters. This is largely a thing of the past now that .NET fully supports generics; however, it does come up from time to time in dealing with legacy code.

Type Extensions
Type extensions enable you to add members to a type, even when you do not have direct access to the type's source or cannot inherit from the type, e.g., when you already inherit from another base class. F# supports two forms of type extensions called intrinsic extensions and optional extensions. Intrinsic extensions appear in the same namespace or module, source file and assembly as the type being extended. Optional extensions do not.

Intrinsic Extensions
To create an intrinsic extension, you use the following syntax:
// Intrinsic extension type typename with [ static ] member self-identifier.member-name = body ... [ end ]

Here, typename is the type being extended. The members (properties or methods) that you add are "hooked onto" this type and act like built-in members. These members may be static members or instance members. Clients do not see a difference between indigenous and intrinsically-extended members. The only restriction is that extension methods cannot be virtual, a.k.a, abstract. In the following example, we define a Message class that we then extend using intrinsic extension.
\\Orignal type type Message() = member this.Send(recipient: string, body: string) = printfn "Send message to %s" recipient \\The author of type forgot to add an Attach member. Let's \\do this with an intrinsic extension. type Message with member this.Attach(entity) = \\attach entity to message true \\Clients can use both methods let m = new Message() let attached = m.Attach("attachment here") m.Send("joe@smith.com", "hey there!")

The key to defining intrinsic extensions lies in the original class name, e.g., Message, paired with the keyword with. Once available, clients call intrinsic extension methods exactly like they call any other methods defined on the class.

Optional Extensions
An optional extension is one that appears outside of the original module, namespace or assembly of the type being extended. We generally use optional extensions we don't have access to the source code of the original type, and don't want to or can't inherit. While intrinsic extensions appear in Intellisense (they are available to reflection), optional extensions do not (they are not available to reflection). Optional extensions must be in modules, and they are in scope only when the module in which they are defined is open. To create an optional extension, we use the following syntax:

// Optional extension type fully-qualified-typename with member self-identifier.member-name = body ... [ end ]

To show how this works, let create an extension to the String class that returns true if the string is a palindrome or false otherwise. Note that I've chosen to make this member static for illustrative purposes. Although the current MSDN documentation (http://msdn.microsoft.com/en-us/library/dd233211(VS.100).aspx) states that optional extensions are compiled to static members, they appear not to function that way you can declare them as static or non-static, and they behave accordingly.
\\How to create an optional extension open System open System.Text type System.String with static member IsPalindrome(s: string) = let l = s.ToLower() let b = new StringBuilder() for i = s.Length - 1 downto 0 do b.Append(l.[i]) b.ToString() = l

Object Expressions
An object expression is an F# expression that creates a new type "on the fly". The new type created is anonymous, meaning it has no accessible name, and must be based on an existing base type, interface or set of interfaces. Object expressions combine the best of lambda functions and component-based programming. We generally use object expressions to create types that are used locally and that participate in specific situations. For example, if you've ever used LINQ to read a database and project the returned data into an anonymous type, you have realized the utility of object expressions. The canonical example used for object expressions is that of object comparison with an eye towards sorting. I think it's a useful example as it captures the essence of object expressions and demonstrates their use in a few lines of code. For this example[7], we'll create a record called Employee and use object expressions to generate classes that can sort Employees based on different criteria.
open System.Collections.Generic type Employee = { lastname: string; salary: float } let employees = [| {lastname="Smith"; salary=60000.00}; {lastname="Jones"; salary=80000.00}; {lastname="Adams"; salary=99000.00}; |] let sortEmployees emps (comparer: IComparer<Employee>) = System.Array.Sort(emps, comparer) emps |> Seq.iter (fun e -> printf "(%s, $%0.2f) " e.lastname e.salary) printfn sortEmployees employees { new IComparer<Employee> with member this.Compare(x, y) = x.lastname.CompareTo(y.lastname) } sortEmployees employees { new IComparer<Employee> with member this.Compare(x, y) = x.salary.CompareTo(y.salary) }

In addition to having the ability to implement interfaces, as just shown, you can use object expressions to inherit from existing classes and override abstract properties and methods as needed. Note that you cannot use object expressions to augment or change a type that is sealed. In the following example, we use an object expression to override a base class method:
type GrandPa() = abstract member WalkThisWay: unit -> unit default this.WalkThisWay() = printfn "GrandPa walks slowly" let Walk(person: GrandPa) = person.WalkThisWay() Walk { new GrandPa() with member x.WalkThisWay() = printfn "I'm walking quickly!" }

The Walk function is passed an instance of a new class, one that inherits from GrandPa and overrides its WalkThisWay virtual member.

In general, object expressions are used primarily to supply dynamic implementations of a single interface; however, as shown, you can use them to selectively override class members as well. The syntax for defining object expressions is as follows:
// When typename is a class { new typename [type-params] arguments with member-definitions [ additional-interface-definitions ] } // When typename is not a class { new typename [generic-type-args] with member-definitions [ additional-interface-definitions ] }

Here, typename represents an existing class or interface type. type-params describes optional generic type parameters. The arguments are used only for class types that require constructor parameters. The member-definitions are overrides of base class methods, or implementations of abstract methods from either a base class or an interface.

Custom EventArgs
In Chapter 13, we discussed events as members of classes. As part of this discussion, we mentioned that events handlers generally work with EventArgs subclasses. Now that we understand inheritance, it's simple to create custom EventArgs derivatives. In the following example, we create an event source, Alarm, an event sink, Guardian, and a custom EventArgs-derived class that is passed from the Alarm to the Guardian when the Alarm triggers.
\\Defines EventArgs open System \\Custom EventArgs type AlarmDetails(msg: string) = inherit EventArgs() member this.Message = msg \\Event source type Alarm() = let triggerAlarmEvent, alarmEvent = Event.create() member this.OnAlarmTriggered = alarmEvent member this.TriggerAlarm(details: AlarmDetails) = triggerAlarmEvent(details) \\custom EventArgs passed to handlers \\Event sink - receives AlarmDetails type Guardian(a: Alarm) = do a.OnAlarmTriggered.Add( fun details -> printfn "*** ALARM! %s ***" details.Message) \\Test let a = new Alarm() let g = new Guardian(a) a.TriggerAlarm(new AlarmDetails("Intruder detected on Level 7!"))

Your custom EventArgs classes can be as sophisticated as you'd like. They should carry enough information so that handlers can use them to intelligently respond to events in an efficient and effective manner.

Custom Delegates
Events are built on top of .NET delegates. Delegates are objects that "wrap" or "point to" methods they are "function objects" so to speak. Clients can invoke the functions that the delegates wrap. In F#, since we can pass functions around as first-class citizens, we can largely forgo using delegates; however, F# supports delegates to interact and interoperate with code written in other .NET libraries and languages. This includes participating in cross-language events, e.g., the ability to raise an event in F# that is subsequently handled in C# and vice versa. In most cases, you don't need to interact with delegates directly, e.g., events hide the fact that you're using delegates; however, there may be circumstances where you need to wrap a function outside the context of events. For example, if you are using a library written in C# and need to provide a callback function to one of its API methods, you could wrap your F# callback function with a delegate and hand that to the C# API. A delegate has the same signature as the function it wraps. In F#, we define delegates using the following construction:
type delegate-typename = delegate of type1 -> type2

With the above syntax in mind, let's suppose we have a simple F# function that takes a string argument and returns an integer, as shown below:
let countDigits (s: System.String) = [for x in s do if Char.IsDigit(x) then yield x].Length

To create a delegate that wraps this function, we would write the following:
type CountDigitsDelegate = delegate of System.String -> int

This is a delegate that wraps a particular type of function one that takes a System.String and returns an int. To use this delegate, we need to create an instance of it, wrap the target function, and then invoke the function (through the delegate). This is exactly what this sample code does:
let d = new CountDigitsDelegate(countDigits) let count = d.Invoke(" hell0 w0r1d ") \\wraps target function \\invoke target function

Note the use of the Invoke method on the delegate instance. Invoke is used to call the method wrapped by the delegate. If the target method takes more than one argument, we need to use a tuple to describe the argument types. In this next example, the CalcRaise function accepts 3 arguments: the last name of an employee (string), the years of service (int), and a current salary (float):
let calcRaise(name: string, yearsOfService: int, currentSalary: float) = currentSalary * (1.0 + (float yearsOfService / 15.0)) type CalcDelegate = delegate of (string * int * float) -> float

Calling the calcRaise function is as simple as invoking it via the delegate's Invoke method:
let c = new CalcDelegate(calcRaise) let newSalary = c.Invoke("smith", 5, 45000.0)

System.MulticastDelegate

The above definitions of delegates are no more than syntactic sugar on top of the .NET System.Delegate and types. As such, the delegate instance is a full-fledged single- and multi-cast .NET delegate object.

Note that delegates are capable of wrapping static functions, non-static functions, static members of types, and non-static members of types. In other words, you can pretty much call anything via a delegate. There is more to delegates that go beyond the scope of this "survival" text, including the ability to combine delegates and to work with them asynchronously. Please consult the MSDN documentation on delegates (http://msdn.microsoft.com/enus/library/ms173171(VS.80).aspx) for a full treatment of this subject.

Attributes
Attributes (http://msdn.microsoft.com/en-us/library/dd233179(VS.100).aspx) in .NET are classes that enable us to attach metadata and code to other structures such as classes, functions, properties, etc. They are compile-time classes, but you should think of them as annotations - notes to the compiler that are attached to things in your source code to qualify or change how the compiler or run-time views those things. Attributes are available at runtime to reflection logic and the .NET runtime recognizes certain, well-known attributes, which affect the way it will interact with the decorated program constructs. Some examples of well-known attributes include declarative transactions, serialization control, and involved with COM interop.

Applying Attributes
In F#, attributes can be applied to functions, methods, assemblies, modules, types (classes, records, structures, interfaces, delegates, enumerations, unions, etc.), constructors, properties, fields, events, parameters, type parameters, and return values. Attributes are not allowed on let bindings inside classes, expressions, or workflow expressions. To apply an attribute to an F# construct, we use the following syntax:
[<target:attribute-name(arguments)>]

Here, target represents the kind of programming construct that the attribute applies to. It is optional and can include assembly, module, return, field, property, param, type and event. If omitted, the attribute is assumed to apply to the next construct appearing in lexical order. is the name of the attribute being used, e.g., DebuggerDisplayAttribute. Note that by convention, the suffix Attribute is generally used in attribute type names; however, in many contexts, this suffix is omitted and the shorter form is used, e.g., DebuggerDisplay.
attribute-name

Since an attribute is a class, it can have a constructor. The arguments shown in the above syntax are those passed to the attribute's constructor. Of course, if the attribute has a default constructor, there's no need to pass arguments. F# attributes support both positional arguments as well as named arguments. Named arguments, if used, must follow positional arguments. In the following example, we apply the DebuggerDisplayAttribute to a custom Movie type that we've defined:

open System.Diagnostics [<DebuggerDisplay("{Marquee}")>] \\Marquee is assumed to be a property or method. type Movie() = \\The debugger will display Marquee's value. let title = "Some Movie" let director = "Talented Person" member this.Marquee = "*** " + title + " by " + director + " ***"

Because we've omitted the target type in the attribute declaration, F# applies it to the type Movie (the element following the attribute lexically). If DebuggerDisplay were restricted to applying to other constructs, the F# compiler would report an error.

Creating Custom Attributes


In addition to the set of well-known .NET attributes we can use, we have the ability to add our own custom attributes to the mix, and attach arbitrary metadata and code to our classes, properties, functions, etc. The .NET runtime does nothing with our custom attributes per se. They are useful for attaching arbitrary information to constructs that our own software might want to interrogate and use[8]. To read attribute data at runtime, your application uses the standard .NET Reflection APIs. Up to this point, we've interacted with attributes ala applying existing ones to our types using the [<attribute>] syntax. Now it's time to discuss how to create our own attributes, given that we're well-versed in type construction and inheritance. Note that there is nothing special about creating attributes in F# vs. other .NET languages. To define a .NET attribute, you need to do a handful of things: Define and build an attribute class and specify what kinds of constructs the attribute applies to Apply the attribute class to the target Optionally use the .NET Reflection APIs to read the attribute information at runtime Let's look at each of these steps in brief here. For all the nitty-gritty details of attribute development, see the MSDN documentation (http://msdn.microsoft.com/en-us/library/sw480ze8.aspx) .

Defining an Attribute Class and It's Usage


To define an attribute class, you define a new type that inherits from System.Attribute (http://msdn.microsoft.com/enus/library/system.attribute.aspx) . For example, let's create an attribute that we can use to restrict method invocation to certain business roles:
[<AttributeUsage (http://msdn.microsoft.com/en-us/library/tw5zxet9(VS.100).aspx) (AttributeTargets (http://msdn.microsoft.com/enus/library/system.attributetargets(VS.100).aspx) .Method ||| AttributeTargets.Property, AllowMultiple=true)>] type SecureMemberAttribute(role: string) = inherit Attribute() let _role = role

We use the AttributeUsage class to define the kinds of programming constructs to which this attribute applies. In this example, we're limiting SecureMemberAttribute's usage to methods and properties. AllowMultiple=true means that we can apply this attribute multiple time to any given element. We may want to do this so that we can apply multiple roles to the list of valid roles, for example. Of course, there are other ways to solve this problem, e.g., by having the attribute class accept an array of strings; however, I just wanted to show the possibilities here.

Applying an Attribute
Now that we have a new attribute, we can apply it. In the following example, we create a BankAccount class, one of whose methods we decorate with our new attribute:
type BankAccount(balance: decimal) = let mutable _balance = balance member this.Deposit(amount) = _balance <- _balance + amount member this.Withdraw(amount) = _balance <- _balance - amount [<SecureMember("Manager"); SecureMember("Supervisor")>] member this.Transfer(fromAcct: string, toAcct: string, amount: decimal) = \\Secure function: transfer funds

Note the multiple application of the attribute. Now, the .NET libraries have no idea what to do with our custom attribute. The runtime will not prevent the calling of the BankAccount's Transfer method. To actually use the SecureMember attribute, your code would need to use Reflection APIs to extract the attribute class and leverage it accordingly.

What You Need to Know


F# supports class inheritance. A class can have at most one base class, although it can additionally support multiple interfaces. You upcast using the :> operator and downcast using the :?> operator. You use the :? operator in match expressions to test the type of a class.

In F#, virtual members are defined using the abstract keyword. F# does not have a keyword virtual. F# supports abstract classes, which can include default member implementations. F# supports interfaces, which cannot include default member implementations. Interfaces can include generic type parameters and participate in inheritance. You can add extensions to existing classes. Extensions come in two flavors: intrinsic, where the extensions are defined in the module of the extended class, and optional, where the extensions are defined outside the context of the module. Anonymous classes can be created on-the-fly in object expressions. You can use and create custom .NET attributes in F#.
However, you can provide a default implementation by also including a separate definition of the member as a method together with the keyword. Doing so is equivalent to creating a virtual base class method in other .NET languages. Such a virtual method can be overridden in classes that implement the interface. [2] Interfaces form the foundation of component-based programming, which is arguably a more robust way to develop systems vs. overusing inheritance. The philosophies governing this argument are beyond the scope of this book. [3] OK, luck didn't have much to do with this. [4] This simply means global functions defined in a module via the let keyword, e.g., let f x = x * x . [5] As a parallel to the upcast expression construct, F# supports the dynamic downcast expression . If the compiler cannot infer a specific target type from context, it reports an error. [6] Example taken from Don Syme's Expert F# book. [7] This example was adapted from the F# Wikibook (http://en.wikibooks.org/wiki/F_Sharp_Programming/Interfaces#Implementing_Interfaces_with_Object_Expressions) . [8]Attributes are used often in frameworks that implement dependency injection and aspect-oriented development models.
[1]

default

Chapter 15 Exceptions & Debugging


Introduction
Exceptions are erroneous or unexpected conditions that arise during the execution of a program. Common exceptions include memory exhaustion, file permission errors, erroneous mathematical calculations, e.g., divide by zero errors, network timeouts, out-of-bounds indexing, accessing a null object, etc. When these types of problems occur, we can use exception handling to deal with them in a standard, structured manner. In this chapter, we will look at how to create, propagate and deal with exceptions. We will also discuss some of the diagnostic and defensive programming tools that F# provides.

Exceptions
F# supports two types of exceptions: .NET-based exceptions and F#-based exceptions. The first part of this chapter assumes the code is working with .NET-based exceptions, the most common scenario. In the second part of this chapter, we explore F#based exceptions.

Handling .Net Exceptions


Since exceptions are the standard way to deal with erroneous and unexpected conditions in .NET, it should come as no surprise that .NET ships with dozens of predefined exception classes that cover all manner of problems. Some of these classes include: ApplicationException, FileNotFoundException, EndOfStreamException, InvalidCastException, etc. In F#, by default, when an exception occurs, the runtime creates an exception object (an instance of a particular exception class) that describes the error in detail. The runtime then begins the process of walking the call stack looking for an exception handler a block of code that has declared itself to be a handler for this type of exception. In exception parlance, we say that the runtime has created and then "thrown" an exception. If the runtime finds a handler capable of processing the type of exception thrown, we say the handler "catches" the exception. It is normally your responsibility to provide a handler to catch an exception, unless you want your program to terminate using the default runtime handler. If the runtime finds the right kind of handler in the call stack of your code, it will pass it the exception object to it. Your handler can then do whatever it likes with the exception, including actions that try to fix the problem, log an error, pass the exception further up the stack, ignore the exception, etc. The runtime stops walking up the stack when it finds a suitable handler. A suitable handler is a trywith expression surrounding calling code on the execution stack. If no suitable handler is found, F# will eventually display an error message and halt the program.

trywith
To handle exceptions in F#, we use trywith to wrap an expression where an exception may occur. trywith has the following general syntax:
try

expressionA expressionB expressionC ... with | pattern1 -> expression2 | pattern2 -> expression3 ...

When we sandwich an expression in trywith, we're telling F# that we want to know about exceptions that occur within that expression. The trywith sets up an exception frame a point in the code that's indicating to F# its interest in exceptions that meet the patterns listed in the with part. When an exception is caught, it is matched against the patterns in the with block, much as if we had a match expression where the exception instance was the argument. A trywith expression evaluates to the last line of the expression between try and with, or to whatever exception handler expression is executed. This means that the expression between try and with, must be compatible with the expression types in the with block, otherwise, the F# compiler will complain that the over trywith expression is inconsistent. It's important to note that try blocks introduce their own scopes, meaning that values declared within try blocks cannot be used in the associated with blocks, since they are out of scope. The try block applies to any call within its call chain. When an exception occurs anywhere within the chain, the runtime will jump to the associated with clause and begin matching the thrown exception object against the patterns specified in the with block. The primary expression code (between try and with) will not complete its execution when an exception is thrown during expression evaluation.

In general, we implement the with block by pattern matching upcasted types of the exception's type via the :? operator. As soon as the matching engine finds a successful pattern match, it executes the expression associated with the pattern (expression2 or expression3 in the above syntax description). If the matching engine cannot find a match, the runtime continues walking up the call stack until it either finds a suitable handler or exhausts the stack. In the following code, we show a representative example of throwing and catching an exception:
let div x y = x / y let a = div 5 0 printfn "%A" a with | :? System.DivideByZeroException -> printfn "You cannot divide by zero!" try

When implementing functions that may throw exceptions, it is a common style to generate option (Some/None) return values. This makes sense, since the function may not be able to return a meaningful result. Using this style, we would rewrite the div example as follows:
let div x y = try Some(x / y) with | :? System.DivideByZeroException -> printfn "Cannot divide by zero!"; None div 10 2 div 19 0

As with all pattern matching, F# will execute the first match that it finds, ignoring all the others. This makes the ordering of exception handlers important, especially since we're comparing against class type. All "handle-able" exceptions eventually derived from System.Exception. So, if you match to System.Exception, that should be the last exception type listed in the handlers. The rule of thumb is to order your handler from most-specific to least-specific, i.e., specific to general. For example, if we were to write the previous example like this
let div x y = try Some(x / y) with | :? System.Exception -> printfn "Always handle exceptions here!"; None | :? System.DivideByZeroException -> printfn "Cannot divide by zero!"; None

we'd have a problem, since the DivideByZeroException would never execute. It would always be superceded by the previous pattern System.Exception. Note in this example the use of the semicolon used to separate the printfn and the return value (None). We can use a semicolon to put several expressions on the same line.

tryfinally
Sometimes when an exception occurs, our application may have resources that it needs to release or half-completed work that it needs to undo. In these cases, using trywith can lead to resources leaks and inconsistent state, since all expressions following the offending one are skipped. This makes cleanup difficult. So, if you have cleanup to do, whether or not an exception occurs, use tryfinally. The syntax is as follows:
try

expression1..n finally expression2..m

The code in the finally block (expression2..m above) will always execute, regardless of whether executing expression1..n generates an exception. If the code in the try block generates an exception, F# transfers control to the finally block, then to the next matching exception handler up the call stack, if one exists. The following code demonstrates the use of tryfinally to clean up a graphics resource:
open System.Drawing let brush = new SolidBrush(Color.Blue) try printfn "About to 'paint' and throw an exception..." let result = 10 / 0 printfn "'Paint' complete" \\should never be executed finally printfn "Cleaning up brush" brush.Dispose()

With tryfinally blocks, the last expression of the try block is considered to be the expression's return type. The finally expression does not contribute to the return type of the expression.

Combining try...with and tryfinally


Often in real-world programs we want to combine the following: executing potentially exceptional code, catching exceptions that occur, and performing come cleanup. F# does not have a trywithfinally construct, but instead favors nesting trywith blocks inside tryfinally blocks, producing a similar effect. In the following example, we see how to use trywith combined with try finally:
open System open System.IO let mutable f: FileStream = null try \\so that all blocks can see it, \\we define it outside all trys

printfn "Opening file" f <- new FileStream("c:\temp\badfile.bin", FileMode.Open) try with Some(f.ReadByte()) | :? FileNotFoundException -> printfn "Cannot find input file"; None | :? Exception -> printfn "Unspecified exception"; None

finally printfn "Closing file" if f <> null then f.Close()

Creating F# Exceptions
In F#, you are not limited to using predefined .NET-based exceptions. You can also define your own F#-based exceptions using the following syntax:
exception exception-type of argument-type

The keyword exception introduces a new exception type. The exception-type is the name of the exception "class", and argumenttype is a tuple of field types making up the contents of the exception. type. Let's take a look at several examples to help illustrate the idea:
exception LightweightException of string exception AccountOverdrawnException of string * decimal

Given the definition of these two F# exceptions, let's see how we can use them in code:
try with

\\// some bad statement () | LightweightException(arg) -> printfn "LightweightException handled" | AccountOverdrawnException(s, d) -> printfn "Account %s is overdrawn by %f" s d

When catching F# exceptions, we need to use different matching patterns than when catching .NET exceptions. With F# exceptions, we match on the exception type and its arguments, as shown above. Even though we need to use different patterns for catching .NET and F# exceptions, we can combine them in the same with block, as illustrated in the example below (the first two patterns match F# exceptions, the last two match .NET exceptions):
exception LightweightException of string exception AccountOverdrawnException of string * decimal try with \\some bad statement () | | | | LightweightException(arg) -> printfn "LightweightException handled" AccountOverdrawnException(s, d) -> printfn "Account %s is overdrawn by %f" s d :? System.IO.FileNotFoundException -> printfn "File not found" :? System.Exception -> printfn "Exception of last resort"

Throwing Exceptions
Not only can we create and handle .NET and F# exceptions, we can also throw or "raise" them explicitly from our code. We may want to do this to inform a caller that something went wrong, e.g., the caller passed in an invalid parameter, we could not perform a calculation, etc. There are two ways to generate exceptions: using raise and using failwith.

raise
We use the keyword raise to generate both .NET and F# exceptions. Using raise is quite simple, as demonstrated by the general syntax:
raise exception

Using raise causes the runtime to generate the specified exception and to start the standard stack unwinding and exception handling process. Here are a few examples:

exception AccountOverdrawnException of string * decimal try let t, f = true, false if t then raise(AccountOverdrawnException("123", 4567.0m)) if not f then raise(System.Exception("bad stuff happened")) | AccountOverdrawnException(acct, amt) -> printfn "Account %s overdrawn by %" acct amt | :? System.Exception as err -> printfn "%s" err.Message

with

rethrow
As of this writing, F# supports the rethrow function, which enables us to re-raise an exception from within an exception handler. This enables our handler to process (or ignore) an exception and then "pass it up" the call stack so that other handlers can process it as well. You can use rethrow only from within an existing exception hander. The following code demonstrates how to use it:
try with let x = 10 Some(x) | :? System.Exception as e -> printfn "%s" e.Message; rethrow()

Note that rethrow does not take any parameters. It re-raises the exception present in the current context.

failwith
To generate an F#-specific exception, you call failwith via the following syntax:
failwith error-string

In response, F# generates an exception of type Microsoft.FSharp.Core.FailureException, which is mapped to the name F# name Failure. You can use the Failure pattern in with blocks as to find an appropriate handler. In the following example [1], we see how to generate and handle an exception generated via failwith:
let divide_failwith x y = if (y = 0) then failwith "Divisor cannot be zero." else x / y let test_divide_failwith x y = try divide_failwith x y with | Failure(msg) -> printfn "%s" msg; 0 let result1 = test_divide_failwith 100 0

invalidArg
F# supports another keyword, invalidArg, that we can use to generate exceptions. We use invalidArg to indicate that a caller has passed to our function, method, etc. in unexpected or invalid argument. invalidArg uses the following syntax:
invalidArg parameter-name error-message-string

Calling invalidArg generates a .NET System.ArgumentException (http://msdn.microsoft.com/en-us/library/system.argumentexception.aspx) where the error-message-string becomes the Message property of the exception object. In the following example, we see how to generate and handle this type of exception:
let kids = [| "Jessica", "Kimberly", "Melissa" |] let getKid n = if (n >=0 && n < kids.Length) then kids.[n] else invalidArg "n" "Please pass a number from 0-2" let k1 = getKid 1 let k2 = getKid 100 Some(k1) with | :? System.ArgumentException as e -> printfn "%s" e.Message; None try

A Note on sprintf
Note the call in invalidArg above. It takes 2 parameters: the name of the invalid argument ("n") and a diagnostic message. The second parameter, the diagnostic message, becomes the thrown exception's Message property. As written, the invalidArg call uses a hard-coded string for the message, ending in 0-2. This is a rather brittle way to handle the error, since at some point in the future, we may want to extend the array or otherwise change its length. What we'd really like to do is format the string based on the calculated length of the array. Unfortunately, trying to directly embed a printf, printfn or tuple-formatted string does not work the compiler rejects the construct.
sprintf,

In order to format strings to be used where printf cannot be used - or anywhere, really - you can use the sprintf function. Using we can rewrite the invalidArg call as follows:

invalidArg "Invalid parameter n" (sprintf "number from 0-%d" kids.Length)

is a handy function for formatting strings in-situ. Of course, being in the .NET environment, you have all of its string formatting facilities at your disposal, e.g., System.String.Format (http://msdn.microsoft.com/en-us/library/system.string.format.aspx) as well.
sprintf

Additional Matching Options


The following list summarizes the different patterns we can use to match exceptions with exception handlers. Matches the specified .NET exception type. Matches the specified .NET exception type and gives the exception a name. This allows us to interrogate the fields, etc. defined on the exception class. Matches an F# exception type and binds the arguments. Matches any exception and binds the name to the exception object. This is equivalent to :? System.Exception as identifier. identifier when condition Match any exception if the condition is true. Remember that .NET-based exceptions are distinct from F#-based exceptions, because .NET exceptions are class instances, where F# exceptions are typically not. We use different pattern matching constructs to match .NET exceptions.
identifier exception-type(args) :? exception-type as identifier :? exception-type

Some Notes on Using Exceptions


Please keep in mind the following rule of thumb: exceptions should be used only to handle truly "exceptional" conditions that arise during program execution. They should not be used to control normal program flow. If they are used to control normal program flow, there are several downsides. First, the semantics of the exception is confused, making room for downstream misunderstandings and subsequent coding errors. Second, exceptions impose a runtime penalty, since an exception frame needs to be created and managed. Many non-trivial software systems tend to use a hierarchy of domain-specific exceptions. This is often a good idea, since it makes clear the domain semantics of a given error, and allows handlers to be clear and precise about their intended function. For example, in an email system, you could imagine exceptions dealing with message fidelity, network connectivity, message sizes, attachments, etc. Domain-centric exceptions provide clarity and consistency throughout the code base, and make clear both the sender's and receiver's jobs. There is a lot more we can say about exceptions and how best to use them; however, a full discussion is beyond the scope of this book. Let's move on and talk about trying to prevent exceptions in the first place.

Assertions
While bugs in software are inevitable, there are techniques that have proven useful in limiting their existence and lifespan. One of the techniques, defensive programming, has many facets, one of which is to use assertions. We use assertion to test conditions before or after we execute a block of code. We refer to these as pre-condition and post-condition checks respectively. The .NET library ships with the System.Diagnostics (http://msdn.microsoft.com/en-us/library/system.diagnostics.aspx) namespace and the System.Diagnostics.Debug (http://msdn.microsoft.com/en-us/library/system.diagnostics.debug.aspx) class. The Debug class has a fair number of methods for helping us write robust code, and F#, being a .NET language, has access to all these facilities. F# directly exposes Debug.Assert from .NET through its the keyword assert. Using assert is simple, as demonstrated by the following syntax:
assert condition

is a Boolean expression. If it evaluates to true, the application proceeds normally, executing whatever follows the assert clause. Otherwise, assert generates a system error dialog box. Due to their "interactive" nature, e.g., they display a dialog box, asserts are most useful during the interactive testing of your software. They are generally used to test pre- and post conditions, e.g., they ensure the values passed to a function are correct, that return values fall within an expected range, etc.
condition

Failures generated by assert cannot be caught by using F# exception handling, and do not affect the F# Interactive Console. This means that they are really only useful during testing, since there's no way to deal with them other than seeing their output (the system dialog box) when they fail. Assertion checking is enabled only when you compile in Debug mode. You compile in Debug mode by defining the constant DEBUG as part of the definitions passed to the compiler (see fsc debug and -define). In the Visual Studio project system, by default, the DEBUG constant is defined in the Debug configuration but not in the Release configuration. This means that assertions have no impact or effect in Release builds by default they are compiled away in Release builds. In the following code, we use assert to ensure that the given input string is not empty.
let Lookup(name: string) =

assert(name.Length > 0) \\// lookup here

To use the other Debug facilities, you can access the Debug class directly. Of course, you also have available to you the full power debuggers, e.g., the Visual Studio debugger, and performance tools that you have with any other .NET language. What I wanted to cover here is the F#-specific debugging facilities, which really just amounts to the assert keyword.

What You Need to Know


Exceptions typically result from unanticipated or problematic conditions that arise during the execution of a program. From an F# perspective, exceptions come in two flavors: .NET exceptions and F# exceptions. When an exception occurs, F# stops evaluation of the current expression and begins to unwind the call stack looking for an appropriate exception handler. If F# finds one, it executes the handler. If not, it displays an error message and terminates the process. You can catch .NET exceptions by wrapping expressions in trywith and pattern matching using :? (or one of its kin). Some code in expressions being evaluated when an exception occurs may not complete execution. You can catch F# exceptions using trywith and matching the exception value in the pattern matching clauses of the with block. You can catch both .NET and F# exceptions using the same with block using the appropriate pattern matching constructs. To ensure that certain code is executed, even if an exception occurs, wrap the expression with tryfinally. F# does not support a combined trywithfinally construct. You can, however, simply embed trywith blocks inside try finally blocks to accomplish the purpose. You can define your own F# exceptions using the exception keyword. You can throw exceptions using built-in F# keywords: raise, rethrow, failwith and invalidArg. F# supports the assert keyword to aid in defensive programming, but does not generate an exception that can be caught with a trywith wrapper.
[1]Taken

from the MSDN documentation (http://msdn.microsoft.com/en-us/library/dd233235(VS.100).aspx) .

Chapter 16 Workflows, Asynchronous & Parallel Programming


Introduction
In this chapter, we discuss workflows. Workflows form the foundation of parallel and asynchronous computing. We will also introduce the concept of monads, the underpinnings of workflow implementations.

Workflows
A workflow, also known as a computation expression, is a mechanism that enables us to implement algorithms that execute a controlled series of expression evaluation steps. With workflows, the output of step 1 serves as the input to step 2, the output of step 2 serves as the input to step 3, etc. This chain of execution continues as long as steps execute without error and intermediate results are valid. If any step in the chain encounters an exception, the evaluation terminates prematurely and all remaining steps are skipped. The value of the workflow expression is the value returned by the last step. We tend to use this style of programming when we need to systematically "build up" a result from constituent parts and we want to check these parts along the way. You may be asking yourself, "Isn't this what programming languages do anyway? Don't algorithms execute step by step already?" In F#[1], the answer is yes, they do. The only thing that needs to be made explicit (in F#) is the checking of the steps' output and the passing of this output to subsequent steps. By using workflows, we can run code "in between" the lines of the explicit code automatically. For example, let's suppose we a program that contains 3 expressions that return Boolean values:
let a = expression1 if a then let b = expression2 if b then let c = expression3

In this example, the act of evaluating the next expression is dependent on checking the result of the previous one. This pattern appears often in programming so often in fact, that it would be convenient to do the check "behind the scenes" or "in between" each line, so that we could write the following, but achieve the same result as above:
let a = expression1 (implict check here) let b = expression2 (implicit check here) let c = expression3

Let's take a look at a more concrete example. We'll do things first without using workflows, then turn around and simplify things using workflows. Let's define a function that checks the existence of a list element. If the element exists, the function returns Some(element), otherwise the function returns None.
let exists e (lst: list<'a>) = let rec find e lst = match lst with | [] -> None | h :: t -> if (h = e) then Some(e) else find e t find e lst

Let's suppose we want to now use this function to ensure that a given list contains a given Web protocol, "http", a given site, and a certain port designation, "80." If it does, we've satisfied all of the conditions of the computation and we download the contents of the URL, otherwise, the computation fails without error:
"www.microsoft.com (http://www.microsoft.com/) ", let mywebaddr = ["http"; "www.microsoft.com"; "1234"; "80"] let download protocol site port = printfn "download: %s %s %s" protocol site port let fetch = let protocol = exists "http" mywebaddr if Option.isSome(protocol) then let site = exists "www.microsoft.com" mywebaddr if Option.isSome(site) then let port = exists "80" mywebaddr if Option.isSome(port) then Some(download protocol site port) else None else None else None

If we really liked pattern matching syntax in F#, we might have choosen to write the above example this way:
let fetch =

let protocol = exists "http" mywebaddr match protocol with | None -> None | Some(p) -> let site = exists "www.microsoft.com" mywebaddr match site with | None -> None | Some(s) -> let port = exists "80" mywebaddr match port with | None -> None | Some(pt) -> Some(download p s pt)

There are a couple of things to notice here. First, this code is "flowing" or cascading the result of a given step (calculation) is used as the basis for performing the next step (calculation). At some point, the cascade ends, either by returning an error value, None, or by returning a valid result, Some(download p s pt). Second, it's somewhat verbose and awkward. Programming in this way gets confusing and error-prone rather quickly. The idiom of "cascading logic" we see here is called a continuation. A continuation takes as input a value and feeds it to a function, sometimes referred to as the "continuation function". The value serves as input to the function, and the function represents the "remaining work" or "the rest of the computation to perform." Using a continuation, we could recode the above example as follows:
let mywebaddr = ["http"; "www.microsoft.com"; "1234"; "80"] let download protocol site port = printfn "download: %s %s %s" protocol site port let fetch = exists "http" mywebaddr (fun p -> exists "www.microsoft.com" mywebaddr (fun s -> exists "80" mywebaddr (fun pt -> download p s pt)))

This is more compact than the previous code examples, but we can do even better. Because this idiom is common in functional programming, F# supports it via a class called a "builder" that's used in conjunction with special workflow syntax. The builder is a class that by convention (and the workflow mechanism depends on it) implements two functions: Bind and Return. The Bind function takes as input a value and a function representing the "rest of the computation" (sound familiar?). The Return function simply returns the value passed into it:
type UrlBuilder() = member this.Bind(v, f) = match v with | Some(x) -> f x | None -> None member this.Return(v) = v

Once we have a builder class, we can create a workflow using it:


let urlbuilder = new UrlBuilder() let fetch = urlbuilder { let! p = exists "http" mywebaddr let! s = exists "www.microsoft.com" mywebaddr let! pt = exists "80" mywebaddr return download p s pt }

The symbol fetch now refers to a workflow. To begin a workflow, we create an instance of the builder class in this case UrlBuilder. This class implements the required Bind and Return methods. We then create a workflow expression using the builder { } syntax for example, urlbuilder { } as in the code example. Within the workflow, notice the let! keyword. let! is a shortcut way to call the builder's Bind method, urlbuilder.Bind(). The first parameter to Bind is the right-hand side of the let!'s equal sign, exists "http" mywebaddr, and the second parameter, filled in by the compiler, is the continuation function, i.e., the function to call if the previous function succeeds. In workflows, this continuation function is simply the function lexically following the given statement. In this example, it's the next "exists" function. If any of the functions in this function chain fails, the workflow terminates prematurely. In addition to let!, workflows support other special keywords. All of these special keywords are simply syntactic sugar they all resolve to methods on the builder class. The exclamation (!) point is the key to having a keyword, e.g., let!, translate to a call to a call on the builder, e.g., Bind. This is powerful ! Since we control the builder's implementation, e.g., Bind, we control the implementation of let! and the other special workflow keywords. For you convenience, the workflow keywords that we use most often are summarized below:
let! calls the builder's Bind method do! calls the builder's Bind method return calls the builder's Return method return! calls the builder's ReturnFrom method yield calls the builder's Yield method

yield! calls the builder's YieldFrom method use calls the builder's Using method, which is expected to call Dispose on the result of the workflow use! calls the builder's Using method, which is expected to call Dispose on the result of the workflow

Your builder classes can also implement additional methods that affect how the workflow behaves. Some of these methods are: ReturnFrom (mentioned above vis-a-vis return!), Delay, TryWith, and YieldFrom. Please consult the F# documentation for details, e.g., you can find the set of methods defined on the Control.AsyncBuilder (http://msdn.microsoft.com/enus/library/ee340369(VS.100).aspx) class (discussed below). You should note that within workflows you can still use standard F# keywords and data structures normally, e.g., let still executes a standard assignment. At the time of this writing, workflows impose two constraints: you cannot define new types within a workflow and you cannot use mutable values you must use reference cells instead. So far, we've seen how workflows can provide a handy way for us to "automatically" and progressively check the return values in a chain of functions. While useful, this is just the beginning. Workflows can help us encapsulate state, perform automatic logging, check for numeric underflows and overflows in calculations, etc. What is really exciting, though, is that we can use workflows to help make parallel and asynchronous programming simple! Enter asynchronous (async) workflows.

Asynchronous (Async) Workflows


Async workflows enable parallel execution, asynchronous execution, and reactive execution and combinations thereof. Let's define these terms so that we're using them consistently:

Parallel execution means starting several operations at once and waiting for all of them to finish before continuing, e.g., downloading 10 stock quotes "in parallel." Asynchronous execution means to start doing something in the background (could be in parallel, too) and notify the original caller when finished, e.g., calling a Web service. Reactive execution means "wait for something to happen" and then respond, e.g., wait for the user to click a button.
To define and use an async workflow, we use the following syntax:
let identifier = async { expression }

The keyword async tells F# to create an instance of the AsyncBuider. This class implements the requisite Bind, Return, etc. methods. The workflow expression is a series of standard F# expressions, including synchronous and asynchronous calls to other functions and workflows. returns an Async<'a> instance, called an async computation, indicated by identifier in the syntax example. The Async's type, 'a, is bound to the workflow's return type via the workflow's final return or return! expression. We use return! when the value is computed via an asynchronous call.
async { }

Note that async workflow does not execute immediately. To execute the workflow, we need to use the returned Async<'a> instance in conjunction with methods in the Async class. The Async (http://msdn.microsoft.com/en-us/library/ee370232(VS.100).aspx) class is a static class that implements members for creating and manipulating asynchronous computations. As of this writing, there are 26 methods documented, enabling a good deal of flexibility. We will discuss the three most-often used functions: Async.Start, Async.Parallel and Async.RunSynchronously[2][3]. is the simplest way to start an async workflow. It does not support the workflow returning a value, meaning that your code does not wait for it to return a result. If you have a workflow whose return value is important, don't use Async.Start use Async.RunSynchronously (described in the next paragraph) instead.
Async.Start

takes a sequence of async computations and queues each one for execution on a thread from the .NET thread pool, as available. Async.RunSynchronously executes these Async.Parallel computations on these threads, and waits for the final result[4]. The async computation normally runs to completion, at which point the .NET thread is returned to the pool, and the result of the computation is handled by whatever physical thread is executing the workflow. This means that the thread doing the async work, and the thread processing the results of the async work can be, and often are, different physical threads. Some literature refers to this as "thread hopping." I mention it here because if you use a debugger to debug async workflows, you might see thread IDs changing during the course of execution.
Async.Parallel

If an async computation throws an exception, Async.RunSynchronously internally catches and re-throws it, making exception handling possible. This is a marked improvement over how C# and other .NET languages handle async exceptions. We often use async { }, Async.Parallel, and Async.RunSynchronously in combination to execute work asynchronously. In the following example, we use these constructs to asynchronously download Web pages and parse their links:
open System.Text.RegularExpressions let urls = ["http://www.google.com/"; "http://microsoft.com/"; "http://www.wordpress.com/"; "http://www.peta.org"] let downloadUrl(url: string) = async {

let wc = new System.Net.WebClient() let matches = wc.DownloadString(url) |> fun html -> Regex.Matches(html, @"http://\S+") printfn Scanning %s, found %d links url matches.Count

At this point in the code, we've set up the async workflow. We now need to run the workflow using functions from the Async class, as shown here:
\\Async calls made here let parseUrls() = Async.RunSynchronously( Async.Parallel [for i in 0..urls.Length-1 -> downloadUrl urls.[i]])

It is very common to see these parallel calls used in conjunction with the forward pipe operator, as shown here:
let parseUrlsPipe() = [for i in 0..urls.Length - 1 -> downloadUrl urls.[i]] |> Async.Parallel |> Async.RunSynchronously

In addition to using the Async class to execute async workflows, we can also use let!, do!, return!, return, etc. in our workflows. As described earlier, F# recognizes the special ! syntax in workflows and binds the associated keywords to methods on the builder class in this case, AsyncBuilder.

let!, do! and return!


Within async workflows, we need to be aware of the differences between let vs. let!, do vs. do!, and return vs. return!. These are compared and contrasted below: binds a value or function to an identifier - nothing new here. In contrast, let! executes an async workflow on its own thread and binds its return value to an identifier. You can simply treat the async operation as the value it returns. Note that when a workflow started by let! returns, the rest of the original workflow will continue to run on the new thread. If you use let! and watch the thread ID of an async workflow over time, you will see the workflow run on different threads as async child workflows complete and return. do executes expressions synchronously, while do! executes expressions asynchronously. do! is used to execute an expression whose return value is uninteresting and can be ignored. return returns a result, while return! executes an async workflow and returns its return value as a result.
let

When you see let!, do!, and return! used in an async workflows, think to yourself, "F# is going run this work asynchronously." This is because the Bind, Return, etc. methods on the associated AsyncBuilder are implemented to create and manage work using multiple threads. Note that if you don't use !, nothing evil happens expressions simply run synchronously. Let's look at an example of an async workflow that that uses plain let and return:
open System.Threading let asyncAdd (x: int) (y: int) = async { let sum = x + y return sum } let add x y = [asyncAdd x y] |> Async.Parallel |> Async.RunSynchronously

Here, we use an async workflow with normal let and return to demonstrate that their use has not changed they do exactly what they've always done. Let's look at another example that uses a more sophisticated async workflow to see let! and do! in action. Note that this example is adapted from one that originally appeared in Ted Neward's 2008 MSDN Magazine article , Use Functional Programming Techniques in the .NET Framework (http://msdn.microsoft.com/en-us/magazine/cc164244.aspx#S8) :
open System open System.IO let TransformImage pixels i = let newImg: byte[] = Array.create 1024 (byte 0) newImg let ProcessImage(i) = async { use inStream = File.OpenRead(sprintf "source%d.jpg" i) let! pixels = inStream.AsyncRead(1024 * 1024) let pixels' = TransformImage pixels i use outStream = File.OpenWrite(sprintf "result%d.jpg" i) do! outStream.AsyncWrite(pixels') do Console.WriteLine "done!" } let numImages = 5 let ProcessImages() =

[ for i in 1 .. numImages -> ProcessImage(i) ] |> Async.Parallel |> Async.RunSynchronously

Note the use of let! this tells F# to execute the async operation (AsyncRead) on a separate thread and to bind the result to the identifier pixels. The code then invokes the TransformImage function (synchronously from the perspective of this workflow), and writes the results asynchronously to an output file via AsyncWrite. The workflow ends by printing a message to the console. When you use let! and do! (and the other async keywords) in a workflow, the F# expressions following the let! or do!, etc. must be asynchronous. In other words, you cannot call let!, do!, etc. with synchronous functions. For example, the following code will fail:
let computeSquaresAsync = async { for i = 1 to 1000 do let! square = i * i \\<<< fails printfn "%d\t%d" i square printfn "done" } |> Async.Start

Since the code i * i does not run asynchronously (the * operator is not async), the let! does not compile. If we change this to plain let, the code compiles. Note that the assignment operator works fine, e.g., let! x = 100 works fine in async workflows. This constraint has implications: If you want to use .NET library code in async workflows, and want to execute the .NET library code asynchronously, make sure to use the async versions of methods and functions. For example, if you want to read and write files asynchronously in a workflow, use System.IO.Stream.AsyncRead and System.IO.Stream.AsyncWrite methods. For useful async extensions to the .NET library, please refer to the F# PowerPack (FSharp.PowerPack.dll).
(http://www.microsoft.com/downloads/details.aspx?FamilyID=E475A670-9596-4958-BFA2-DC0AC29B4631&displaylang=en)

A Note on Locking
The F# literature on the Web is somewhat confusing with regards to what async workflows offer with respect to protecting data from multithreaded access. In a nutshell, the answer is "none." The benefits we get from using async workflows are somewhat dependent on the "whole" of functional programming, including the use of immutable data structures. By using immutable data structures, we naturally circumvent a class of multithreaded "gotchas." If your program does use mutable data structures, you need to take the same precautions in F# that you would with any other language capable of executing multiple threads simultaneously. You need to lock shared state for writes, etc. A full discussion on multithreaded and parallel programming is beyond the scope of this text. For more information, please see the MSDN documentation on parallel programming (http://msdn.microsoft.com/en-us/library/dd460693(VS.100).aspx) .

Handling Exceptions in Async Workflows


In async workflows, exceptions are not caught and handled by default. This means that if an async workflow throws an exception, the process will terminate. Luckily, we have a way to deal with this situation by using Async.Catch (http://msdn.microsoft.com/en-us/library/ee353899(VS.100).aspx) , as shown in the following example[5]:
let square_if_even n = async { do if n % 2 <> 0 then failwith "not even" return n * n } let get_square x = square_if_even x |> Async.Catch |> Async.RunSynchronously |> function | Choice1Of2 answer -> printfn "ok: %d" answer | Choice2Of2 except -> printfn "exn: %s" except.Message

sets up an exception handler for the async workflow. If the async workflow returns successfully, the first match pattern, Choice1of2 is matched. If an exception occurs, the second pattern, Choice2of2 is matched. The Choice type, shipped in F#'s core library, is defined as follows (note the capital "O" in Of):
Async.Catch type Choice<'T1,'T2> = | Choice1Of2 of 'T1 | Choice2Of2 of 'T2

Cancelling Async Workflows


When executing an async workflow, you may want to cancel it, i.e., terminate it prematurely, before it completes normally. For example, you may want to cancel a workflow if its execution time execeeds a certain threshold, or the user grows impatient waiting for an operation to complete. Async workflows support cancellation. To set up an async workflow so that it can be cancelled, you need to run it through the TryCancelled function.
open System open System.Threading

\\Async workflow that takes a long time. let longOperationAsync delay = async { printfn "doing time-consuming thing..." printfn "waiting %d seconds" delay let wait = delay * 1000 Async.Sleep(delay) |> ignore printfn "time-consuming operation complete" } \\Cancellation function. \\Called if the async workflow is cancelled. let onCancelled (c: OperationCanceledException) = printfn "operation canceled: %s" c.Message \\Sets up async workflow that can be cancelled. \\Associates async workflow with cancellation function. let delay = 15 Async.TryCancelled(longOperationAsync delay, onCancelled) |> Async.Start if delay > 10 then \\>10 secs is too long for us to wait! Async.CancelDefaultToken()

Notice the call to CancelDefaultToken(). This call cancels the most recently executed async workflow.The " DefaultToken" in the function name refers to the underlying mechanism by which F# enables cancellation a cancellation token. Whenever you start an async workflow, e.g., using Async.Start, F# assigns the workflow a CancellationToken. A cancellation token is a .NET structure defined in the System.Threading namespace that tracks whether or not the async workflow has received a cancellation request, e.g., via CancelDefaultToken. Whenever the async workflow executes a let! or do!, the underlying AsyncBuilder checks the status of the workflow's CancellationToken. If the token is marked "cancelled", the workflow terminates and the associated cancellation function, a.k.a., compentation function, is called. You can assocate your own CancellationToken with a workflow explicitly by creating a CancellationTokenSource object and passing the CancellationTokenSource.Token member to the Async methods that start the workflow, e.g., Async.Start.
let cts = new CancellationTokenSource() let asyncwf = Async.TryCancelled(longOperationAsync delay, onCancelled) Async.Start(asyncwf, cts.Token)

Note that the forward pipe syntax does not work here, since we need to pass the Async.Start method a tuple. To cancel the associated workflow, we do so via the CancellationTokenSource instance:
cts.Cancel()

F# supports a convenience function[6] that enables us to launch a cancellable async workflow in one fell swoop:
Async.StartWithContinuations( longOperationAsync delay, (fun result -> printfn "workflow completed ok"), (fun ex -> printfn "exception handler here"), (fun cncl -> printfn "cancellation handler here"), cts.Token)

This function starts the async workflow and calls the approprite completion function on a normal completion, exception or cancellation.

Monads
Monads are constructs that stem from a branch of mathematics known as category theory, which in part deal with the translation or morphing of mathematical structures, including functions. In functional programming, monads play a role in that they can help enable function composition and chaining while enabling controlled side effects. Let's suppose, for example, we want to execute a series of functions: f -> g -> h (f executes and passes its output to g, etc.). To make this work, f's output must be compatible with g's input, and g's output must be compatible with h's input. Let's suppose we also want to log each function call in the chain as it executes, thus introducing a side effect explicitly. We can satisfy both of these requirements via using monads. Formally, a monad is a type (class) needs to implement a function called bind, a function called return, and a type constructor that allows for the composition of monadic functions, i.e., functions that take monads as arguments and/or return monads as return values. In the documentation, monad types are generally denoted by a capital M. and return are complementary functions. return takes a plain value and wraps it in a monad type, e.g., takes an int and returns a monad object that wraps the int. bind does the reverse it takes a monad, unpacks its plain value, and passes it to the next function in the chain. The next function in the chain will accept a monadic type that can be created from the output of the previous function.
bind

In the F# documentation for workflows (http://msdn.microsoft.com/en-us/library/dd233182(VS.100).aspx) , which are built on monadic constructs, you will see bind and return defined as follows

Bind: M<'a> * ('a -> M<'b>) -> M<'b> Return: 'a -> M<'a>

As you can see, the bind method, Bind, takes an M<'a> and a function that converts an 'a to an M<'b> and produces an M<'b>. The return function, Return, takes a plain 'a and returns a 'a wrapped in a type M. The bind and return functions work together to ensure that functions can be called in a chain, while the implemention of the bind method can support side-effects, e.g., logging each function call or running code on a separate thread. The builder classes, e.g., our custom urlbuilder and the built-in AsyncBuilder, discussed earlier, adhere to this monadic pattern.

What You Need to Know


Monads are constructs used in functional programming that enable the explicit and ordered chaining of functions and the controlled execution of side effects. We use F# workflows to implement programs in a monadic style. Workflows hide the lexical complexity of nested (bind(return))) call chains via syntax sugaring. Workflows are built using builders that implement bind and return, at the very least. Builders may implement additional methods as well. Async workflows are workflows that use multiple threads to accomplish work asynchronously. Async workflows use threads from the default .NET thread pool. When using async workflows, you need to be aware of the difference between let and let!, do and do!, and return and return!. The ones that use the bang (!) symbol initiate and require async operations.
This is not the case in pure functional languages such as Haskell, since these language evaluate all expression lazily, enabling the language runtime to reorder execution. [2] The old name of this function was Run . As of this writing, Run is deprecated. Use RunSynchronously instead. [3] See MSDN article Build Concurrent Apps from Simple F# Expressions by Chance Coble (http://msdn.microsoft.com/enus/magazine/cc967279.aspx) for an interesting read. [4] The fact that RunSynchronously waits for the thread to finish is where the "synchronously" part of the name comes in. [5] Adapted from Matthew Podwysocki's blog: http://weblogs.asp.net/podwysocki/archive/2008/08/15/async-computation-expressionsresource-and-exception-management.aspx. [6] I adapted this example from a preview copy of Chris Smith's Programming F# book.
[1]

Chapter 17 Packaging Your Code & Interfacing with .NET Libraries


Introduction
In this chapter, we discuss two pragmatic topics: how to package your code for consumption, and how to consume code in other libraries. The intra- and inter-language capabilities of .NET languages offer a certain appeal for many developers, enabling them to apply the most appropriate language to the task at hand without sacrificing overall system compatibility.

Organizing Your F# Code


Namespaces
A namespace is the highest level of code organization. A namespace enables us to organize our code into logically related areas of functionality by grouping program elements under a common naming umbrella. The namespace becomes an intrinsic part of the name of the elements within it. Namespaces are used primarily to structure our code hierarchically and to avoid namec conflicts. To specify a namespace, you use the following syntax:
namespace [parent-namespaces.]identifier

Let's suppose we're creating an enterprise application, and we decide to divide the functionality into several tiers a UI tier, a business tier, and a database tier. To keep code logically and semantically separated, we could define namespaces that segragate this functionality, e.g.:
namespace UI namespace Business namespace Database

We can include "sub" or "child" namespaces under a "parent", to further refine and separate out our code's functionality, using dot notation e.g.:
namespace Database.SQLServer namespace Database.SQLServer.Client namespace Database.MySQL

Namespaces cannot directly contain values and functions. Instead, they can contain modules, types and do bindings. Namespaces can be declared explicitly (as shown above) with the namespace keyword, or implicitly via declaring modules. Namespaces can span multiple files in a single project or compilation unit. The term namespace fragment describes the part of a namespace that is included in one source file. Namespaces can also span multiple assemblies. For example, the System namespace includes the whole .NET Framework, which spans many assemblies and contains many nested ("child") namespaces.

Modules
Another grouping mechanism that F# provides is the module. An F# module is a simple mechanism for grouping types, values, function values, and the code in do bindings. F# compiles a module into a common language runtime (CLR) class that has only static members. We declare modules using the following syntax:
// Top-level module declaration module [accessibility-modifier] [qualified-namespace.]module-name declarations // Local module declaration module [accessibility-modifier] module-name = declarations

Modules impact identifier scope. Inside a module, identifiers are all visible to one another, but are not visible externally. To reference identifiers defined in external modules , your code must full qualify the identifier names, e.g., MyModule.myIdentifier or use the open keyword as discussed in Chapter 2. By default, each module is contained in a single source file. The entire contents of the source file make up the module, and if the module isn't explicitly named, it gets the name of its source file, with the first letter capitalized, e.g., a file named fileIO.fs would produce a module called FileIO.

Top Level Modules


To explicitly name a module, we use the following syntax at the top of the F# source file:
module [accessibility-modifier] [qualified-namespace.]module-name declarations

When we explicitly define a module in this way, we are defining a top-level module. Providing a top-level module is optional, and if we choose to do so, the module name must appear as the first declaration in the source file. A top-level module lends its name to the entire source file, which means that all elements in the source file are intrinsically compiled into the static class produced by the compiler. Note that you do not need to indent structures within a top-level module to have them be included in the module. In the following example, we show an F# file (program.fs) that contains a top-level module called Utils:
module Utils let ReverseString s = () let IsPrime = ()

The way this is written, this code defines two functions that are named Utils.ReverseString and Utils.IsPrime. If we were to omit the top-level module declaration, these functions would have been part of the default module Program, which would have been generated by F# based on the name of the file, program.fs, with the first letter capitalized.

Local Modules
In contrast to top-level modules, F# enables us to define local modules, which are used to name and organize small sections of a larger file. To define a local module, you use the following syntax:
module [accessibility-modifier] module-name = declarations

Note the equal sign (=) at the end of the module name, as well as the indented module declarations. Similar to namespaces, module names can contain dots, allowing us to organize and structure the name into a hierarchy of meaningful parts. In the following example, we have a file (program.fs) that will provide for us the default top-level module name Program. Within program.fs, we define two local modules that organize and scope the contained constructs:
\\Default module generated is Program module Employee = let mutable Name = let CalcPay emp = () module Company = let GetEmployees = () let Hire e = ()

This code defines two local modules, Employee and Company. Employee and Company define two separate naming scopes. To access from outside this file, for example, clients would need to access Employee.CalcPay, as this is it's full name. Continuing with this example, here is a snippet of code used to access CalcPay:
CalcPay open Program Employee.CalcPay 123

Because Employee is a module in its own right, we can also code this call as follows:
open Program.Employee CalcPay 123

Nested Modules
F# also enables is to nest modules within one another. Nested modules must appear indented under their parents and their names cannot include dots. In the following example, we define three local modules with increasing degrees of nesting. Through this example, we also demonstrate how modules introduce scope:
\\Default module generated is Program module GrandPa = let Name = "Philip" module Dad = let Name = "Adam" module Son = let Name = "Tom"

The following code snippet makes use of these nested modules:


open Program.GrandPa let printNames = printfn "%s" Name printfn "%s" Dad.Name printfn "%s" Dad.Son.Name

As you can see here, the same identifier, Name, can be used in each module without any problems, due to the fact that the full name, e.g., Dad.Name, is unique.

Module Aliases
It is sometimes convenient to provide short or distinct names to modules. This can help with potential name clashes and/or save

a bit of typing. To access a module and give it an alias, you use the following syntax:
module alias = existing-module-name

Let's look as an example. Here, we define a long module name, and define a function inside the module:
module MyVery.Long.Module.Name let MyFunc() = printfn "MyFunc"

We can access MyFunc in another file using a module alias, like this:
module MyModule = MyVery.Long.Module.Name MyModule.MyFunc()

Note that some older texts say that you can access namespaces using this syntax. As of this writing, this is deprecated functionality. You are now only able to alias modules.

Order Matters
F# requires that types, values and functions are defined before they can be used. This means that if you require a particular construct in a definition, this construct must be already defined. Let's consider an example. Suppose we have two modules, Company and Employee. As part of an Employee's definition, definition we want to record information about the Company. This means that the Employee module will need information from the Company module. If we build our F# application using the command-line compiler, fsc, we need to pass the Company.fs file to the compiler followed by Employee.fs, e.g., fsc Company.fs Employee.fs o Corp.exe. This will compile fine; however, if we switch the order of the files, we'll get a compilation error to the effect that the module Company is not defined. This ordering "rule" is reflected in Visual Studio as well. In the Solution Explorer window, the order in which the files are listed is the order in which they are compiled, i.e., that they are passed to the F# compiler. To change the ordering of the files, you can right-click on a file name (in Solution Explorer) and select Move Up or Move Down, among other options. You must be asking yourself what to do if we have classes that are circularly dependent. Recall from our discussion of types that in order to define types that reference one another, we must use a conjoined definition using the and keyword, as in the following example where Actor depends on Film and Film on Actor :
type Actor(f: Film) = do () and Film(a: Actor) = do ()

What this means in terms of modules is this: classes that are circularly dependent must be defined in the same module using the and keyword.

Execution
Program execution begins with the last module passed to the compiler. All of the elements in this file/module execute, starting from the top of the file and working toward the bottom, as you'd expect. If your program consists of more than one module, none of the other modules' top-level statements will execute until one of their values is accessed. Let's look at an example. In this example, we have three files: Module1.fs, Module2.fs and Program.fs. These are listed in order below (#light is defined in each):
Module1.fs printfn "I am Module1" let sayHello() = printfn "Module1 saying hello!" \\Module2.fs printfn "I am Module2" let sayHello() = printfn "Module2 saying hello!" \\Program.fs -> module Program implied printfn "I am the main program"

Assume these are compiled in the order shown, making Program.fs the last module passed to the compiler. As a result, when the program begins executing, all of Program.cs's top-level will run. This also means that, as written, none of the statements in Module1.fs nor in Module2.fs will execute. The output of this program, as expected, is I am the main program. If we augment the Program.fs file to open and use these other modules, the top-level statements in the modules may or may not execute. Merely opening the module is not sufficient to stimulate execution, nor is calling a function. To ensure that a module's top-level statements execute, a client must access one of the values in the module via a running function or expression. In the following, updated code, Program.fs opens both modules, calls a function in each, and accesses a value in only one of them:
\\Module1.fs printfn "I am Module1" let public mod1Val = 100 let sayHello() = printfn "Module1 saying hello!"

\\Module2.fs printfn "I am Module2" let public modVal2 = 200 let sayHello() = printfn "Module2 saying hello!" \\Program.fs -> module Program implied open Module1 open Module2 printfn "I am the main program" Module1.sayHello() let m2 = Module2.modVal2 Module2.sayHello()

The output of running the application, i.e., running Program.fs is as follows:


I am the main program Module1 saying hello! I am Module2 Module2 saying hello! Press any key to continue . . .

As shown, Module1's top-level statement is not executed, since we never accessed its value (mod1Val). We merely called Module1's sayHello function, which executed correctly. In contrast, we did access Module2's value (modVal2), which stimulated F# executing its top-level statements. We also called a function in Module2, which executes, as expected.

Functions
F# also supports encapsulation and scoping via local functions, a.k.a., inner functions (as discussed in Chapter 8). Inner functions are those that are defined within other functions. In functional programming, we implement inner functions to hide complexity from clients, e.g., the client does not need to know a function is recursive, and to break up complex functions into manageable parts. From the perspective of code organization, it's a technique that you should be aware of. Here is an example of an inner function from the F# Wikibooks:
let sumOfDivisors n = let rec loop current max acc = if current > max then acc else if n % current = 0 then loop (current + 1) max (acc + current) else loop (current + 1) max acc let start = 2 let max = n / 2 \\largest factor, apart from n, cannot be > n / 2 let minSum = 1 + n \\1 and n are already factors of n loop start max minSum printfn "%d" (sumOfDivisors 10) \\prints 18, because the sum of 10's divisors is 1 + 2 + 5 + 10 = 18

Signature Files
A signature file is a mechanism for controlling the accessibility of a module's types, values, functions, etc. You can create a signature file per F# source file. Each signature file shares the name of the source file with which it's associated, expect that it has an .fsi extension. A signature file describes the namespaces, modules, types, and members of its associated source file. We use signature files to control which elements of the source file are exposed to the outside world, and which remain private to the file itself. As a rule of thumb, constructs not listed in the signature file are considered to be private to the file itself. If no signature file is found in the project (or via the command line), F# employs default accessibility as specified via public, internal and private. The format of a signature file is rather simple. For each type, method, etc. that we want to expose, we use the signature for the element, which acts as a complete specification of the functionality being exposed. The syntax for a type signature is the same as that used in abstract method declarations ala interfaces and abstract classes. Signature files work with Intellisense, too. To expose a value or function using a signature file, we use the keyword val. To expose a type, we use the keyword type. Signature files can include attributes that further refine the information exposed to clients. The two attributes used in signature files are [<Sealed>] and [<Interface>], which describe types that cannot be extended (Sealed) and types that are interfaces (Interface) respectively. Generally, you auto-generate signature files using the command-line compiler option --sig and then manually remove the entries that you want to keep private. The MSDN documentation (http://msdn.microsoft.com/en-us/library/dd233196(VS.100).aspx) describes several rules regarding signature files, reproduced here for your convenience:

There are several rules for type signatures: Type abbreviations cannot be hidden by signatures. Records and discriminated unions must expose either all or none of their fields and constructors, and the order in the signature must match the order in the implementation file. Classes can reveal some, all, or none of their fields and methods in the signature.

Classes and structures that have constructors must expose the declarations of their base classes (the inherits declaration). Also, classes and structures that have constructors must expose all of their abstract methods and interface declarations. Interface types must reveal all their methods and interfaces. The rules for value signatures are as follows: Modifiers for accessibility (public, internal, and so on) and the inline and mutable modifiers in the signature must match those in the implementation. Editorial comment: I found that I could override accessibility via the signature file. For example, in my module (below), the SuperCalc type class is marked public, but I could cause it to be marked internal by the compiler via the signature file. It appears as though the signature file can override the accessibility modifiers in the code. The number of generic type parameters (either implicitly inferred or explicitly declared) must match, and the types and type constraints in generic type parameters must match. If the Literal attribute is used, it must appear in both the signature and the implementation, and the same literal value must be used for both. The pattern of parameters (also known as the arity) of signatures and implementations must be consistent.
As of this writing, Visual Studio 2008 using F# CTP 1.9.6.16 does not produce valid signature files. If I compile my application using the Visual Studio-generated FSI files, the compiler reports problems with the files - issues with val and incomplete structures. That said, the command-line compiler seems to produce valid signature files just fine. So, for now, to generate signature files, I'd suggest using the command line. Let's look at an example. Our example application consists of two files: Module1.fs and Program.fs:
\\Module1.fs => Module1 module name type Calc() = member this.Add x y = x + y type public SuperCalc() = member this.Mul x y = x * y \\Program.fs open Module1 let new Calc() let sum = c.Add 1 2

To produce a signature file for Module1.fs, we execute the following command-line command:
fsc -sig:Module1.fsi Module1.fs

The compiler will produce a file called Module1.fsi. Here's what it looks like:
#light module Module1 type Calc = class new : unit member Add end type SuperCalc = class new : unit member Mul end

-> Calc : x:int -> y:int -> int

-> SuperCalc : x:int -> y:int -> int

Now, I'd like to hide SuperCalc from the outside world. To do this via the signature file, I open Module1.fsi in the Visual Studio (or any) editor and remove the SuperCalc entry. The updated signature file looks like this now:
#light module Module1 type Calc = class new : unit -> Calc member Add : x:int -> y:int -> int end

Now I can compile the program as follows:


fsc Module1.fsi Module1.fs Program.fs

Signature files are optional.If present, they must precede their implementation files in compilation order on the compiler command line. If you're using Visual Studio to build your projects, this means ensuring that each signature file comes before it's associated implementation file in the Solution Explorer. Executing the above command produces Program.exe, which contains the correct modules with the specified accessibility. The Calc class is public, while the SuperCalc class is marked as internal. You can use .NET Reflector (http://www.redgate.com/products/reflector/) to verify this. My recommendation is that you rely on in-situ accessibility modifiers, i.e., modifiers specified in the F# code itself, rather than

rely on specifications in the sig file. To my mind, this is simpler, as you only need to specify accessibility once and only once. It also reduces the number of files you need to maintain. That said, many F# programmers like to use signature files for two reasons: They can be used to make entities public for the duration of the file (because signature files are per implementation file), but then private to the subsequent files of the project. They can provide a documented, public interface to consumers, which can be a clean, condensed and easy-to-read format vs. having consumers wade through lots of code.

Deploying Your F# Code


You've built something useful in F#. Now you're ready to deploy it. A great deal has been written about how to build, sign, version and deploy .NET applications. I am not going to rehash that material here. Creating F#-based assemblies is no different from creating assemblies in other .NET languages. Using F#, you create .NET EXEs and DLLs. The F# compiler supports a host of options (http://msdn.microsoft.com/en-us/library/dd233171(VS.100).aspx) , including those for static linking libraries, defining debug directives, etc. The F# EXEs and DLLs that you create are linked to create one or more .NET assemblies. Please consult the MSDN library regarding the options you have with respect to deploying .NET assemblies. Don Syme's Expert F# also covers deployment in detail.

The AutoOpenAttribute
The AutoOpen attribute can save your clients a bit of work. If you want to set up your own assembly or module so that the F# runtime automatically makes available its contents, you can apply the AutoOpen attribute at the assembly or module level[1]. Here is what the MSDN documentation (http://msdn.microsoft.com/en-us/library/dd393787(VS.100).aspx) has to say:

You can apply the AutoOpen attribute to an assembly if you want to automatically open a namespace or module when the assembly is referenced. You can also apply the AutoOpen attribute to a module to automatically open that module when the parent module or namespace is opened.

Interfacing with the .NET Libraries


F# Server, C# Client
Once you've developed, tested, debugged and packaged your F# code, you may need to integrate it into a larger system. It's not far-fetched to assume that some of the libraries in this larger system are written in C#. In this section, we'll demonstrate how to create an F# library (DLL) and access if from C#. To get started, we'll create a new Visual Studio solution called Fusion. This solution will consist of an F# library project and a C# Console project.

Simple Interactions
In our solution, the F# library defines project a namespace FSharpCalc and a top-level module CalcEngine from which it exposes a type Calculator and a function GCD. Here are the definitions:
namespace FSharpCalc module CalcEngine \\Calculator type type Calculator() = member this.Add member this.Sub member this.Mul member this.Div

x x x x

y y y y

= = = =

x x x x

+ * /

y y y y

\\Greatest Common Divisor function let rec GCD x y = if y = 0 then x else GCD y (x % y)

When we compile this code, we produce a DLL called FSharpCalc.dll. Note that the namespace is important in that it enables the C# client to access the contents of the library via its standard using directive. If you omit the namespace in the F# code, the default module machinery kicks into gear, which causes the module to be named after the source file. My recommendation is to use namespaces whenever you can. Using namespaces has several benefits including making the code clear and transparent, helping to avoid name collissions, and simplifying consumption. In our sample solution, the client is a simple C# Console application that exercices the F# library's functionality. In order to access library, the C# project needs a reference to the FSharpCalc.dll. Once it has a refernece, the C# client accesses the library's namespace via a standard using directive. From there on in, the client can create Calculator objects, call their methods, call the global GCD function, etc. Here is the source code for the C# Console application.
using System; using FSharpCalc; namespace CSharpClient

class Program { static void Main(string[] args) { var c = new CalcEngine.Calculator(); int s = c.Add(1, 2); int p = c.Mul(3, 5); int g = FSharpCalc.CalcEngine.GCD(8, 20); Console.WriteLine("Sum={0},Product={1},GCD={2}", s, p, g); Console.ReadLine(); } }

While simple, this example demonstrates the core ideas of calling F# code from C#. To be pragmatic, let's add some functions to the CalcEngine module that deal with more sophisticated data types such as arrays, lists and events to see how to deal with them properly. Along these lines, we have added the following function to the F# library:
\\Sum a list using fold (we could use sum as well) let SumList (lst) = let accumulate acc x = acc + x let sum = Array.fold accumulate 0 lst sum

This function accepts a list of values and uses Array.fold to compute the arithmetic sum. Since we're using the Array type to conduct the fold operation, F#'s type inference system will expose an Array type to client, i.e., C# will see the argument lst as an array type. This means that the client is expected to pass in an array argument. This is exactly what the C# client does, as shown here:
using System; using FSharpCalc; namespace CSharpClient { class Program { static void Main(string[] args) { int[] myIntArray = new int[5] { 1, 2, 3, 4, 5 }; int sum = CalcEngine.SumList(myIntArray); Console.WriteLine("sum of 1-5 = {0}", sum); Console.ReadLine(); } } }

To make the F# code more generic, we can replace the Array implementation and expose the collection as an IEnumerable by using the Seq type.
\\Sum a list using fold let SumList (lst : #seq<'a>) = let accumulate acc x = acc + x let sum = Seq.fold accumulate 0 lst sum

Of course, the type argument the client supplies must implement a plus (+) operator for us to avoid a run-time error (x = acc + x could fail). Let's update the C# client to an IEnumerable:
using System; using System.Collections.Generic; using FSharpCalc; namespace CSharpClient { class Program { static void Main(string[] args) { \\Pass in a List<T> var myList = new List<int>(new[] {10, 20, 30, 40}); var sum = CalcEngine.SumList(myList); Console.WriteLine("sum of 10-40 by tens = {0}", sum); Console.ReadLine(); } } }

We can also calls functions that accept arguments of type unit and return unit as well (unit -> unit). For example, we can add the following code to FSharpLib:
\\Function that takes nothing and return nothing let printHello() = printfn "Hello from FSharpCalc.CalcEngine!"

and call it from C# like this:


CalcEngine.printHello();

Note that when we define the function in F#, we use the empty ( ). This ensures that C# sees the function as a function type and not a property.

Events
Because F# is a fully-supported .NET language, almost every construct you define in F# can be consumed by C# and other .NET languages. The tricky part is getting the F# types and the C# types to align. Let's look at an example that can be somewhat vexing events. In order to define events in F# that can be consumed by C#, you need to use delegates and the [<CLIEvent>] attribute. In the following example, we reconstruct the FSharpLib to define an event that's fired whenever the Add method is called:
\\Calc Library namespace FSharpCalc module CalcEngine open System \\Event arg type AddEventArgs(msg: string) = inherit EventArgs() member this.Message = msg \\Event delegate type AddEventDelegate = delegate of obj * AddEventArgs -> unit Calculator that can now raise an event type Calculator() = \\Create Event<handler, args>: let ev = new Event<AddEventDelegate, AddEventArgs>() member this.Add (x: int) (y: int) = let sum = x + y \\Fire event ev.Trigger(this, new AddEventArgs(String.Format("Added {0} and {1}", x, y))) sum \\Magic attribute that exposes the event to other .NET languages [<CLIEvent>] member this.OnAdd = ev.Publish

In this example, when we define the AddEventDelegate via the delegate keyword, the F# compiler generates a MulticastDelegate. The MulticastDelegate is general purpose, and is generally sufficient to implement cross-language events; however, if you want, you can specify the specific delegate type that F# should use via the DeletegateEvent (vs. using the plain Event as we've done above). In the following example, taken from a hubFS post by Tomas Petricek (http://cs.hubfs.net/forums/thread/10552.aspx) , you can see how these classes are used:
\\Declare class for testing, which can be used from C# type Test() = \\Declare event with 'EventHandler' delegate let evt1 = new DelegateEvent<System.EventHandler>() \\Declare event that'll use standard F# generic delegate type let evt2 = new Event<System.EventArgs>() \\Expose the first event as C# event [<CLIEvent>] member x.Event1 = evt1.Publish member x.Foo1() = evt1.Trigger([| box x; box System.EventArgs.Empty |]) \\trigger it \\Expose the second event as C#-compatible event [<CLIEvent>] member x.Event2 = evt2.Publish member x.Foo2() = evt2.Trigger(System.EventArgs.Empty) \\trigger it!

High-Order Functions
Another interesting situation that arises when building F# components for C# consumption revolves around high-order functions. When you design an F# function that accepts function arguments, or returns a function, how do you call this from C#? We answer this question by way of an example. First, we define an F# function, filterStringsFromList that filters a list of strings based on a filtering function. The caller will pass filterStringsFromList the filtering function to use. This example was adapted from Robert Pickering's Foundations of F# book:
let filterStringsFromList f (l : List<string>) = new List<string>(l |> Seq. filter f)

As you can see here, we're using standard F# high-order function semantics. The first parameter to filterStringsFromList is a standard F# function. The second parameter is a list of strings to filter. Under the covers, F# exposes high-order function parameters via built-in type called FastFunc. This means that .NET client applications that want to call this function need to work

parameters via built-in type called FastFunc. This means that .NET client applications that want to call this function need to work with FastFunc types. To gain access to the FastFunc type, we include a reference to the FSharp.Core.dll in our C# project. The FSharp.Core.dll includes a helper type, FuncConvert that C# applications can use to wrap local functions, making them compatible with F#'s FastFunc type. In the following C# client example, we use the types defined in FSharp.Core.dll to call the HighOrder.filterStringsFromList function defined in our F# library:
static void PrintJNames() { var names = new List<string>( new string[] { "Jessica", "Kimberly", "Jill", "Melissa" }); Converter<string, bool> pred = s => s.StartsWith("J); FastFunc<string, bool> ff = FuncConvert.ToFastFunc<"string", "bool">(pred); IEnumerable<string> jnames = HighOrder.filterStringsFromList(ff, names); foreach (string name in jnames) { Console.WriteLine(name); } }

A few notes about the code sample are in order. The Converter (http://msdn.microsoft.com/en-us/library/kt456a2y.aspx) class is a .NET class used to convert one type to another. Here, we are using it to wrap a lambda function and create a delegate, which is required by FuncConvert.ToFastFunc. We then use FuncConvert.ToFastFunc to convert this delegate into a FastFunc so that we can pass it into the F# filterStringsFromList function. While this works perfectly well, I think it's fair to say that working with FastFunc objects is somewhat awkward. Luckily, we have a simpler solution. If we begin in F# by defining our filterStringsFromList function using a delegate vs. a raw function, this makes calling the function from C# simpler. Let's see what it looks like:
namespace FSharpLib open System open System.Collections.Generic module HighOrder = \\New version that uses delegate vs. raw F# function for filter function let filterStringsFromList (del : Predicate<string>) (l : List<string>) = let f x = del.Invoke(x) new List<string>(l |> Seq. filter f)

The new version of filterStringFromlist is only slightly different from the original. The first argument, the Predicate, is now a .NET class that inherits from the MulticastDelegate class. We can use any MulticastDelegate-derivate to expose our F# function arguments to the .NET-world-at-large. Often, we use the delegate types from the System namespace's Func<> family of classes, e.g., Func<T, TResult>. Please consult the MSDN documentation for details on Func<> delegates (http://msdn.microsoft.com/enus/library/system.aspx) . Now that F# is exposing its function argument like this, we can bypass FastFuncs and instead use C#'s lambda functions directly. We demonstrate this in the following example:
using System; using System.Collections.Generic; using FSharpLib; namespace CSClient { class Program { static void Main(string[] args) { var names = new List<string>( new string[] { "Jessica", "Kimberly", "Jill", "Melissa" }); var jnames = HighOrder.filterStringFromList(s => s.StartsWith("J"), names); foreach (string name in jnames) { Console.WriteLine(name); } } } }

Clearly, this is much cleaner and more intuitive than the original code. The moral of this story is: if you're writing high-order functions that you intend to be callable by C# and other .NET clients, expose your arguments via delegates.

C# Server, F# Client
In contrast to accessing F# from C#, it's more likely that your F# code will leverage libraries already written in C# and other .NET languages. This section deals with this scenario.

Simple Interactions
You can use F# to consume libraries written in other .NET languages. We do this all the time when using classes from the .NET Base Class Library (BCL). In the following example, we build a C# library that exposes a class for downloading Web pages. We then consume this library from an F# Console application. Here is the code for the C# library:
using System.Net; using System.Text;

namespace CSLib { public class HttpHelper { public string GetWebPage(string url) { var req = new WebClient(); var payload = req.DownloadData(url); return new ASCIIEncoding().GetString(payload); } } }

Consuming this library from F# is straight forward. We simply add a reference to the C# library in our F# project, open the exposed namespace, and make calls as usual. Here is the F# Console application:
#light open CSLib let hh = new HttpHelper() let yahoo = hh.GetWebPage("http://www.yahoo.com") printfn "%s" (yahoo.ToString())

Lists and Collections


Lists and collections are fundamental to programming. With the inclusion of generics (and the upcoming contravariance and covariance support in C# 4.0), the majority of developers will probably use the generic-based collections defined in System.Collections.Generic (http://msdn.microsoft.com/en-us/library/system.collections.generic.aspx) . Let's write a C# class that uses these data structures, and then examine how to access them from F#.
using System.Collections.Generic; namespace CServer { public class MyType { public List<string> GetNames() { return new List<string>( new string[] { "Jess", "Chee", "MissyP" }); } public int CountThese<T>(IEnumerable<T> e) { int count = 0; foreach (object o in e) { ++count; } return count; }

We can use these (very contrived) methods from F# as follows:


open System.IO open CServer let o = new MyType() let names = o.GetNames() names |> Seq.iter(fun name -> printfn "%s" name) let c = o.CountThese (seq { 1..10 }) printfn "count = %d" c

As you can see, it's straight-forward to access C# lists and enumerables from an F# client.

ref and out


By default, in .NET, value types are passed by value. This means that a copy of the value is passed into a function or method. In contrast, reference types are passed via their memory addresses, meaning that a change to the argument is, in reality, a change to the original. To override this default argument-passing behavior, C# uses two keywords, ref and out. Both keywords instruct the C# compiler to pass arguments by reference. The only difference between the two keywords is that out arguments must be initialized (set to a value) before the called function exits. ref parameters are not subject to this restriction. From F#, when we call a function or methods that uses ref and/or out parameters, we need to use reference cells to ensure changes in the values are reflected back to us. In the following example, we create a simple C# class with methods that do not use ref or out, use ref, and use out:
namespace CServer { public class MyType { public void foo(int i) { ++i; }

public void bar(ref int i) { ++i; } public void quux(out int i) { i = 999; }

We can see the effect of calling these methods from F# using the following F# Console application:
#light open System open CServer let x = new MyType() let a, b, c = 123, 456, 789 Console.WriteLine("before: {0} {1} {2}", a, b, c); x.foo a letb' = ref b x.bar b' let c' = ref c x.quux c' Console.WriteLine("after : {0} {1} {2}", a, !b', !c'); Console.ReadLine() |> ignore

As you can see, to call methods that accept ref and out arguments , we use F# reference cells. Since we are not modifying the core value (we are modifying the reference cell), we do not need to make the value mutable. Recall that in order to dereference these cells, we use the bang (!) operator. Note that in the case of calling method foo, we do not use reference cells, since the argument is not decorated with ref or out. Of course, passing reference types, i.e., object-based types, is done without argument decoration. We see this in the following example:
namespace CServer { public class MyType { public int MyNum = 123; public void foo(int i) { ++i; } public void bar(ref int i) { ++i; } public void quux(out int i) { i = 999; } public static void ModMyType(MyType o) { o.MyNum = 12345; } } }

Given this C# server code, we can it from F# with standard object (reference) semantics, as shown here:
open System open CServer let x = new MyType() printfn "before: x.MyNum = %d" x.MyNum MyType.ModMyType(x) printfn "after : x.MyNum = %d" x.MyNum Console.ReadLine() |> ignore

Cleaning up resources
In F# programming, you will probably call into the .NET libraries and leverage classes from the BCL. Many of the classes in the BCL manage finite resources, e.g., file handles, graphics contexts, etc. allocated by the underlying operating system. In order to avoid memory leaks, etc., you need to deallocate these resources when you're through using them. The standard protocol for doing this in .NET is to use the IDispose (http://msdn.microsoft.com/en-us/library/system.idisposable(VS.100).aspx) interface, call the Dispose method for the given resource object. To make calling Dispose natural and painless, F# provides two keywords: use and using. The use keyword takes the following form:
use value = expression

It provides the same functionality as a let binding with the added feature of instructing the F# compiler to call Dispose on the value when the value goes out of scope. The following example shows how to leverage the use keyword to automatically close a

value when the value goes out of scope. The following example shows how to leverage the use keyword to automatically close a file:
open System.IO let writeToFile filename (str: string) = use theFile = File.CreateText(filename) theFile.WriteLine("{0}", str) \\F# calls theFile.Dispose() automatically here writeToFile @"c:\temp\poem.txt" "Mary had a little lamb..."

The using function has the following form:


using (expression) function-or-lambda

In a using expression, expression creates the object that must be disposed. The result of the expression (the object that must be disposed) becomes an argument to the subsequent function or lambda expression. The following example demonstrates the using expression with a lambda. Of course, you could replace the lambda with a function call that takes a single argument of the type created:
open System.IO let writeToFile filename (str: string) = using (File.CreateText(filename)) (fun theFile -> theFile.WriteLine("{0}", str) ) writeToFile @"c:\temp\song.txt" "You are my sunshine, my only sunshine..."

The using function and the use binding are nearly equivalent ways to accomplish the same thing; however, the using keyword provides more control over when Dispose is called. When you leverage using, Dispose is called at the end of the function or lambda expression; however, when you utilize the use keyword, Dispose is called at the end of the containing code block, when the use-d object goes out of scope.

COM Server, F# Client


We can use F# to call COM servers. The good news here is that accessing COM via F# is pretty much the same as accessing it via C# and other .NET languages. The beauty of COM is that it is a language-agnostic interface, resulting in uniform client access. Because .NET has been around for a while, and has matured, you may find a managed wrapper already available for the COM components you'd like to access, e.g., Microsoft Office 2007. In cases where a managed wrapper does not exist, you can access the COM objects directly. To access COM objects directly from F#, run the type-library import tool ( TLBIMP (http://msdn.microsoft.com/enus/library/tt0cf3sx(VS.80).aspx) ) on the executable (DLL or EXE) that contains the definitions of the COM objects. TLBIMP will create an OO wrapper assembly around the COM objects contained in the executable. The resulting assembly can be used like any other assembly you add a reference to the assembly in your Visual Studio project or use the-r switch on the F# compiler. Once loaded, the assembly provides convenient access to the underlying COM components. In the following example, based on one from Pickering's book, we run TLBIMP on the Speech API DLL executable to generate a wrapper around the COM object model. On my machine, the Speech API is found here: C:\Windows\System32\Speech\Common. Now that we have a wrapper DLL, we can use Visual Studio to add a reference to it. Once we've done that, we can use the classes exposed by the wrapper to access the underlying COM functionality. In the following F# example, we create an instance of the main speech class and have the computer say something:
open speech let sp = speech.SpVoiceClass() sp.Speak("I'll be back.", SpeechVoiceSpeakFlags.SVSFDefault) |> ignore

While writing this chapter, I experimented with other COM servers. What I found was that TLBIMP and F# converted all the required constructs to F#-consumable types very convenient!

P/Invoke
The last interop scenario that we'll consider is using platform invoke, more commonly referred to as P/Invoke. The P/Invoke plumbing, which is an intrinsic feature of the CLR, enables F# to call unmanaged code, e.g., code in the Windows API and other C-based DLLs. To use data structures, classes and functions from external libraries, e.g., the Windows API, you need to tell F# where these constructs reside. This means telling F# the name of library, e.g., USER32.DLL, and the names of the specific constructs you want to access. To do this, we open the System.Runtime.InteropServices namespace and use the the DllImport attribute. The general syntax is:
[<DllImport( arguments )>] extern declaration

In the following example, we use P/Invoke to display a message box:

open System.Runtime.InteropServices [<DllImport("user32.dll")>] extern int MessageBox(int32, string, string, uint32) \\hwnd, text, caption, type MessageBox(0, "Hello from F#!", "F# Survival Guide", 0u) DllImport tells F# where the external function (or structure) lives. The extern keyword tells the F# compiler that the referenced function is defined outside of the current file or module. Together, DllImport plus extern give us access to external constructs.

Given the C-based history of the Windows API, many API calls take pointers as arguments. When dealing with APIs that take pointers as arguments, we need to tell F# that the argument is a pointer via using the asterisk symbol (*) in the function definition, and using the address-of symbol (&&) when calling the function. In the following example, we use F# to call the GetDiskFreeSpace function defined in kernel32.dll.
open System.Runtime.InteropServices [<DllImport("kernel32.dll")>] extern bool GetDiskFreeSpace( string lpRootPathName, uint32* lpSectorsPerCluster, uint32* lpBytesPerSector, uint32* lpNumberOfFreeClusters, uint32* lpTotalNumberOfClusters) let mutable spc, bps, fc, tc = 0ul, 0ul, 0ul, 0ul let ok = GetDiskFreeSpace("c:\\", &&spc, &&bps, &&fc, &&tc) printfn "Results %d %d %d %d" spc bps fc tc System.Console.ReadLine()

Note that many Windows APIs accept structures and pointers to structures as arguments. To call these APIs, you need to define F#-centric definitions of the structures that you can pass into the API. For example, let's look at the GetLocalTime() function defined in kernel32.dll (http://msdn.microsoft.com/enus/library/ms724338(VS.85).aspx) . This function takes a pointer to a SYSTEMTIME structure. F# does not ship with a definition of this structure, nor does it support the concept of a "header file" from which to draw definitions. Therefore, we need to define typemappings ourselves, mapping F# types to C types. In the following example, we demonstrate how to do this, using GetLocalTime() as an archetype:
open System open System.Runtime.InteropServices [<Struct>] type SYSTIME = val wYear: int16 val wMonth: int16 val wDayOfWeek: int16 val wDay: int16 val wHour: int16 val wMinute: int16 val wSecond: int16 val wMilliseconds: int16 [<DllImport("kernel32.dll")>] extern void GetLocalTime(SYSTIME* t) let mutable t = new SYSTIME() GetLocalTime(&&t) printf "Local date and time: " printfn "%d-%d-%d %02d:%02d" t.wYear t.wMonth t.wDay t.wHour t.wMinute Console.ReadLine() |> ignore

As you can see, we defined an F# structure that matches, field for field, the C-based structured defined in the API documentation. We then repeat the use of the technique of passing the function a pointer to the relevant construct. Whenever you shuttle types from .NET to unmanaged code, you're implicitly working with a .NET component called the marshaller. The marshaller is responsible for shipping managed type to unmanaged code and vice versa. The marshaller can handle many cases of type-shuttling transparently; however, it's not omnipotent, and occasionally needs some help. Some APIs, for example, accept complex structures that themselves contain pointers, etc. When working with these types, you may need to help the default marshaller via using the MarshalAsAttribute defined in System.Runtime.InteropServices. This class tells the runtime how to shuttle and transform data between the managed and unmanaged worlds. A full discussion of marshalling complex data structures is beyond the scope of this "survival guide" text. For more information, check out the MSDN documentation on .NET marshalling (http://msdn.microsoft.com/en-us/library/aa446538.aspx) via P/Invoke and the Web site http://www.pinvoke.net (http://www.pinvoke.net/) . It is a wiki-style site that documents P/Invoke signatures, etc.

What You Need to Know


Namespaces enable you to broadly organize your code in a consistent, cross-assembly manner. I recommend always

defining your own namespaces for any non-trivial project. Modules provide a way to organize your code at the file level. F# compiles modules to a class containing only static members. Modules come in two flavors: file-level or "top-level" that encompass the entire contents of a given file and "local" that help subdivide a larger file into logical sections. Local modules can also be nested. Modules may be aliased. This is usually done to abbreviate long module names. The load order of modules matters. Forward references do not exist by default in F#. Signature files provide a way to document and publish the public interface to your module. You can package your F# code in assemblies consisting of EXEs and DLLs. This is no different from any other .NET language. F# is interoperable with C# and other .NET languages. F# can call into COM servers. F# can call into the core Windows API via P/Invoke.
[1]

We will look at an example of this when we discuss packaging and deployment of F# libraries.

Das könnte Ihnen auch gefallen