Ryan Riley (17) [Avatar] Offline
#1
Having covered function composition and partial application, I would have thought you would include some of those options in the examples, if only to remind the reader of what we've just read. The two F# examples for mapping on a filtered list are:

let names = List.map fst (List.filter (fun (_, pop) -> 1000000 < pop) places)

and

let names = places |> List.filter (fun (_, pop) -> 1000000 < pop) |> List.map fst

Those are great, but it would help to see how to apply some of the advanced function applications. I was having trouble applying them myself to this problem but finally came up with two options, though I'm not positive why the type annotation is necessary on the second:

let names = places |> (List.filter (snd >> ((<smilie 1000000)) >> List.map fst)

and

// Can't use 'a; must use string. Why is that?
let findNames : ((string * int) list -> string list) = List.filter (snd >> ((<smilie 1000000)) >> List.map fst
let names = findNames places
Tomas Petricek (160) [Avatar] Offline
#2
Re: Section 6.7.2, Page 168, filter and map examples
Hi,
thanks for the feedback. I originally thought about having a similar example in the chapter (at least it should be in the online source code you can download from www.functional-programming.net), but then, I wasn't really sure whether I should put it in the book or not.

In this case, the code using function composition isn't particularly shorter and to me, it doesn't seem to be more elegant. In fact, I think it's less readable then the straightforward version, so I probably wouldn't use it. It seems to me that function composition is used less often in F# than for example in Haskell. That said, it's still, no doubt, an important functional construct, but I think a simple example is enough for an introductory book.

Regarding your the code samples, the online source code contains this version (using just one function composition):
let names = places |> List.filter (snd >> ((<smilie 1000000)) |> List.map fst

The issue you're facing with the second example is "Value restriction" (see for example http://strangelights.com/fsharp/wiki/default.aspx/FSharpWiki/ValueRestriction.html). The problem is that when you define "findNames" it is a value intead of a function and values like this cannot be declared as generic. This means that the compiler needs to know the exact type. If you want to make it generic, you'll need to turn it into a function by writing:

let findNames x = x |> List.filter (snd >> ((<smilie 1000000)) >> List.map fst

I hope this answered your questions. I'd be still happy to include some more examples of function composition somewhere in the book, but I think this example may scare some people and isn't really showing the best F# programming practices (at least from some point of view).

Thanks!
Tomas
Ryan Riley (17) [Avatar] Offline
#3
Re: Section 6.7.2, Page 168, filter and map examples
I like your explanation. You may want to consider adding such an explanation in that part of the chapter. I wouldn't know from the current text that I shouldn't use function composition there, even though you had just covered it. Better still, you already have the text in your comment above! smilie Thanks!
Tomas Petricek (160) [Avatar] Offline
#4
Re: Section 6.7.2, Page 168, filter and map examples
Thanks!
I'm just editing chapter 6, so I'll try to add something like this to the manuscript. I hope there is still some space for this!

Tomas
jdfagan (4) [Avatar] Offline
#5
Re: Section 6.7.2, Page 168, filter and map examples
I found this article/example to be very helpful in my understanding of when and why to use function compositions (vs. the pipeline operator):

http://blogs.msdn.com/b/chrsmith/archive/2008/06/14/function-composition.aspx

Cheers,

JD