Functional Programming using F#

Michael R. Hansen and Hans Rischel
Cambridge University Press 2013
ISBN 9781107019027

Corrections:

Page 20, line 18:

Give an evaluations

should be:

Give an evaluation

Page 24 line 3 from bottom:

the Unicode alphabet

should be replaced by:

UTF-16

Page 25, the first text line on the page should be extended as follows:

where the last one denotes the space character. A character is converted into its UTF-16
code by use of the function int, e.g. int 'a' = 97 and an UTF-16 code is converted to
a character by use of the function char, e.g. char 97 = 'a'.

Page 25, add following paragraph at the end of the page:

The character 'y' is sometimes a consonant (in 'yesterday', for example)
and sometimes a vowel (in 'city', for example). In Exercise 2.14 you are
asked to revise the above programs to accommodate this fact.

Page 26, line 9:

val it : string = "\"1234\""

should be:

val it : string = ""1234""

Page 31, the first paragraph on the page should be replaced by:

     Overloading is extensively used in the .NET library (e.g. int: char -> int giving the
UTF-16 code, and int: string -> int converting a digit string to integer value). Typing
of arguments is frequently needed to resolve ambiguities. The user may declare overloaded
operators and functions inside a type declaration as explained in Section 7.3.

Page 38, Table 2.6, format of decimal constants should be:

{-}digitsM   or   {-}digits.digitsM

Page 39, insert the following just above Summary:

   Floating-point values should be used with care, because two expressions with same value
may yield different results when evaluated using floating-point arithmetic - try for instance
1.2=1.0+0.1+0.1. The reason is as follows:
   A floating-point value (type float or float32) consists of binary numbers mant and
exp called mantissa and exponent, each comprising a fixed number of bits. The floating-point
value represents the number mant · 2exp. A number like 110 can hence not be represented
by a floating-point value because it can't be written in the form m · 2n with integers m
and n. The number may, however, be approximated by a floating-point value representing a
number close to 110. The F# conversion of the string "0.1" to a float value yields such
an approximation.
   An arithmetic operation on floating-point values comprise a rounding of the resulting
mantissa in order to fit the format, and the operation is therefore only an approximation to
the corresponding (mathematical) operation on the represented numbers.
   This book uses floating-point values only in a few examples (mainly of geometric nature)
and they are otherwise considered outside the scope of the book. You may consult books on
scientific computing for further information about how to use floating-point values.

Page 41, add the following exercise:

2.14 The character 'y' is sometimes a consonant (in 'yesterday', for example)
and sometimes a vowel (in 'city', for example). Revise the programs on Page 25
to accommodate this fact.

Page 48, line 20-22:

same function name or operator to arguments of different types, but an overloaded operator
... when applied to float's).

should be replaced by:

same function name or operator to arguments of different types, but the types of the arguments
has to be resolved during the compilation in case of overloading.
    Polymorphism in F# can also be obtained using interface types (cf. Page 192).

Page 48, just above: 3.3 Example: ... add the following:

The string function (cf. Section 2.12) applies to values of any type, but it is not polymorphic.
The function toString declared by:
   let toString x = string(box x)
is polymorphic and applies string to any value.

Page 55, line 17:

let b = ...

should be:

let d = ...

Page 61, line 15 from bottom:

Delete the word 'raise' from the program.

Page 63, line 3:

The following text and example should be added after line 3:

An exception declaration defines a constructor with corresponding set of tagged values of type exn, for example:

    exception Error of string;;

and another version of the area function from Page 61 could raise an Error exception:

    let area x =
        if not (isShape x)
        then raise (Error "not a legal shape")
        else ...



Page 81, line 7 to 6 from bottom:

expression (a closure) is considered a value expression because it is only evaluated further
when applied to an argument.

Should be:

declaration with argument pattern is always allowed at top level because a further evaluation
will only take place when the function is applied to an argument.

Page 82, line 18 to 19:

... does not contain type variables, ...

Should be:

... does not contain type variables or object interface types, ....

Page 84, line 8:

declare a auxiliary function

should be:

declare an auxiliary function

Page 90, last line:

p q [ x0; x1; x3; ... ; xn-1 ]

should be:

p q [ x0; x1; x2; ... ; xn-1 ]

Page 91, exercise 4.22, second line:

All commas in lists should be semicolons, i.e. the lists should be
[a0 ; a1 ; ...; an] and [2; 0; 0; 1].

Page 94, Table 5.1: The formulas for fold and foldBack should be:
fold  f  e  [x0 ; x1 ; ...; xn-2 ; xn-1]  =  f   (f   ( ... (f   (f   e   x0)  x1) ... )   xn-2)   xn-1
   and
foldBack  g  [x0 ; x1 ; ...; xn-2 ; xn-1e  =  g   x0   (g   x1   ( ... (g   xn-2   (g   xn-1   e)) ··· ))

Page 103, line 15 from bottom:

g x0 (g x1 (foldBack g [x1 ;x2 ; ...;xn-1] e))

should be:

g x0 (g x1 (foldBack g [x2 ;x3 ; ...;xn-1] e))

Page 105, line 12 from bottom:

tation is based on a balanced binary tree representation ...

should be:

tation is based on a balanced binary tree representation (cf. Page 136) ...

Page 113, line 10 from bottom:

sets of entries

should be:

set of entries

Page 114, line 11 from bottom:

using balanced binary trees, ...

should be:

using balanced binary trees (cf. Page 136), ...

Page 147, Exercise 6.12, line 2 from bottom:

Declare the functions depthFirstFold and breadthFirstFoldBack on list trees, cf. Section 6.6.

should be:

Declare the functions depthFirstFoldBack and breadthFirstFold on list trees, cf. Section 6.6.

Page 155, add the following just above Table 7.3

Note that a terminating double semicolon (;;) may not occur anywhere
between the start of the type definition and the end of the type extension.

Page 162, Table 7.8:
Replace all occurences of

(x,y)
with

(x1,y1)

Page 166, Table 7.10, line 2 from bottom the table:

win.Show();;

should be:

win.Show();; // For Mono-platforms: replace 'win.Show()' with 'Application.Run(win)'

Page 166, line 1 from bottom:

5. The window is shown (win.Show()).

should be:

5. The window is shown using win.Show() on Windows and Application.Run(win) on Mono-platforms.

Page 168, Table 7.11:
Line 3 from top:
Replace

let map f ...
with:
let mapC f ...
Line 1 and 3 from bottom:
Replace

map
with:
mapC

Page 169, line 3 in Table 7.12 and line 2 below Table 7.12:
map
should be:
mapC

Page 172, line 8:

You should chose your own names ...

should be:

You should choose your own names ...

Page 183, line 13:

val it : int list = [1; 2]]

should be:

val it : int list = [1; 2]

Page 188, line 2:

reeds a text file

should be:

reads a text file

Page 188, line 12:

let file = ...

should be:

use file = ...

Page 189, line 17:

A selections of operations

should be:

A selection of operations

Page 189, Table 8.2, line 11:

Remove elements of other set

should be:

Remove elements outside other set

Page 191, line 18 from bottom:

set<'a>

should be:

Set<'a>

Page 191, line 15 from bottom:

map<'a,'b>

should be:

Map<'a,'b>

Page 194, line 13:

stores the enqueued value in the first free array location.

should be:

stores the enqueued value in the array location after the last value in the queue.

Page 208, line 8 from bottom:

gives a dramatically improvement

should be:

gives a dramatic improvement

Page 209, line 8 from bottom:

tail-recursive declarations of the above form in this subsection.

should be:

tail-recursive declarations of the above form in this section.
     Tail calls are handled by F# in a special way: The stack frame of the preceding
function call is popped off the stack before the stack frame of the tail call is
pushed onto the stack. This is feasible because the tail call terminates any use
of bindings generated by the preceding function call.

Page 216, Exercise 9.7, Question 1:

A version fibA: int -> int -> int -> int ..... F-1 and F-2.

should be:

A version fibA: int -> int -> int -> int with two accumulating parameters a and b, where fibA n a b = Fn when a = F0 and b = F1.

Page 217, a new exercise:

Exercise 9.15

Page 229. Replace the six lines just above Table 10.5 with:

     The line-break string "\r\n" indicates change of line in a text file handled by Text I/O.
The I/O functions insert and remove line-breaks in a proper way: An input line obtained by
calling ReadLine contains no line-breaks while each call of WriteLine adds a line-
break at the end of the line. The I/O functions perform automatic conversion between the
UTF-16 character encoding used in the program and the UTF-8 encoding used in the file.

Page 222, Table 10.2:

Add extra line in top section:    .    Matched by any character

Page 232, line 18:

system will in this case release the resources when the binding of the identifier reader
cannot be accessed any longer from the program. One usually ...

should be:

system will in this case release the resources when the program execution exits from the block
containing the use binding of the identifier reader. One usually ...

Page 237, line 9:

can be found in

should be:

can be found in [9].

Page 243

The format of the MSDN web-pages has been changed after the chapter was written.
This gives corrections to Page 243:

Page 243, line 3-7 should be:
<a data-tochassubtree="true"
href="/en-us/library/ee353413.aspx" id="hh782276_VS.110_en-us"
title="Microsoft.FSharp.Collections Namespace">
Microsoft.FSharp.Collections Namespace</a>
Page 243, line 8:

System.Collections Namespace (F#)

should be:

Microsoft.FSharp.Collections Namespace

Page 243, line 9:

ee370255

should be:

ee353413

Page 244 and Table 10.16:

The format of the HTML sources of the MSDN web-pages has been changed after the chapter was written.
nextInfo and getWebRefs functions have been changed accordingly.
The corrected Page 244 and Table 10.16 are shown here

Page 253, line 5:

Extracting the third element

should be:

Extracting the fifth element

Page 254, Table 11.1, type for map:

map: ('a -> 'b) -> seq<'a> -> seq<'>

should be:

map: ('a -> 'b) -> seq<'a> -> seq<'b>

Page 255, Line 7 from below:

n ≥ i

should be:

i ≥ n

Page 268, Line 16 and Figure 11.2, Line 11:

SqlDataConnection<"Data Source=IMM-NBMRH\SQLEXPRESS;

should be:

SqlDataConnection<"Data Source=IMM-NBMRH\\SQLEXPRESS;

Page 280 line 9-10:

t.Bind ...
t.Return ...

should be:

member t.Bind ...
member t.Return ...

Page 297, first line:

let numReg = Regex @"\G\s*((?:\053|-|)\s*[0-9]+)";;

should be:

let numReg = Regex @"\G\s*((?:\053|-|)[0-9]+)";;

Page 297, line 9 from bottom:

The associations of the operators are capture in

should be:

The associations of the operators are captured in

Page 307, line 9:

been introduced above, so the grammar can ...

should be:

been introduced above, so the grammar on Page 297 can ...

Page 317, last 3 lines in Table 13.3 should be:

Makes current task a wait item. The argument is a function that is called with the
triple of continuations as the argument. This function should save one or more of
the continuations in variables. The task continues when a saved continuation is called.

Page 320, line 2:

continuation.

should be:

continuation (determined e.g. by a try...with... construct, cf. Section 3.10).

Page 320, from line 13 to bottom:

The examples are not correct. The corrected Page 320 is found here.

Page 321, line 6 to 8:

Each execution ... in the function declaration.

should be

Each execution of an asynchronous computation with possible cancellation should have a
fresh cancellation token and this object should be disposed afterwards. The below
dialogue program ensures this by means of a local use-binding (cf. Page 327).

Page 322. Add this comment as line 2 in Table 13.4:

// To be used only in single-thread operation

Page 323, Table 13.5, line 1 from bottom the table:

window.Show();;

should be:

window.Show();; // For Mono-platforms: replace 'window.Show()' with 'Application.Run(window)'

Page 324, line 5 to 6:

Note that the program ... for the book.

should be

The start-up using Async.StartImmediate implies that the event-driven dialogue
program is executed by a single thread. This ensures the integrity of mutable data,
including the event queue. The complete program is found at the homepage of the book.

Page 340 lines 1 to 3:

Elements in HTML appear in pairs of start and end elements, and some elements may
contain attributes. The line break element <br /> is considered a (degenerated) pair of
start and end element <br></br>.

should be

Elements in HTML appear in pairs <name ... > ... </name ... > of start and end element,
and some elements may contain attributes. An element of form <... /> (like the line break
element <br />) is considered a (degenerated) pair of start and end element.

Pages 344 and 345:

The format of the HTML sources of the MSDN web-pages has been changed after the chapter was written.
The nextLevelRefs program has been changed accordingly.
The corrected pages 344 and 345 are shown here

Comments to: Michael R. Hansen
Last update: August 20, 2020