tempusfugit (128) [Avatar] Offline
#1
5.2.3 Using tuples compositionally (p.111)

"val printMessage : int * int -> string -> unit
The signature tells us that the function takes two arguments."

Maybe this is obvious if you are an F# master. But to a neophyte this may not be so obvious. It would be clearer with some additional information, i.e.:

> let printMessage (x:int, y:int) (s:string) = ();;
val printMessage : int * int -> string -> unit


Initially I wasn't sure if I could possibly be looking at

> let printMessage (fsmilieint * int -> string)) = ();;
val printMessage : (int * int -> string) -> unit


which results in a decidedly different but only slightly different looking signature.

It takes some practice to spot the small things that make a big difference.

One of the more frustrating aspects of F#'s type inference is that while it by and large is a blessing, it turns into a curse when one lacks the practice in specifying explicit type annotations on the rare occasions where one has to apply - usually fairly complex - type constraints.
Tomas Petricek (160) [Avatar] Offline
#2
Re: 5.2.3 Using tuples compositionally (Clarification)
Hi, thanks for the feedback!
It definitely takes some time to learn how to read F# type signatures (especially because currying which is an important aspect is explained at the end of chatper 5). I like the idea of adding "stub" declaration of the function to make it easier to understand this bit, so I just added that to the manuscript.

Thanks again for the suggestion,
Tomas