Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Whats wrong with s.Count(Char.IsLetter)

F#

let s = "bugs 42 bunny"
s.Count(fun c -> Char.IsLetter(c))
s.Where(fun c -> Char.IsLetter(c)).ToArray()
s.Where(Char.IsLetter).ToArray()
s.Count(Char.IsLetter) // error

Why does only the last line fail to compile:

Error FS0002: This function takes too many arguments, or is used in a context where a function is not expected

like image 201
citykid Avatar asked May 30 '14 18:05

citykid


2 Answers

I think it's an edge case of type inference wrt member overloading. The difference between Count and Where is that the former has two overloads with different number of arguments.

You can work around by specifying conversion from F# function to System.Func<_, _>:

s.Count(Func<_, _>(Char.IsLetter))

Of course, it's even uglier than the corresponding version:

s.Count(fun c -> Char.IsLetter(c))

You could file a bug at https://visualfsharp.codeplex.com/workitem/list/basic so that it may be fixed in the F# vNext.

Note that in F#, you don't often use Linq functions. You can either do:

s |> Seq.sumBy (fun c -> if Char.IsLetter c then 1 else 0)

or

s |> Seq.filter Char.IsLetter |> Seq.length
like image 124
pad Avatar answered Nov 11 '22 15:11

pad


Daniel appears to be correct about the type inference problem.

It doesn't look as nice, but the following appears to work.

Char.IsLetter |> s.Count
like image 40
Guvante Avatar answered Nov 11 '22 16:11

Guvante