Working with strings in F# is sometimes a bit uncomfortable. I would probably use the same code as Dario. The F# grammar doesn't allow using constructors as first class functions, so you unfortunately cannot do the whole processing in a single pipeline. In general, you can use static members and instance methods as first class functions, but not instance properties or constructors.
Anyway, there is a really nasty trick you can use to turn a constructor into a function value. I would not recommend actually using it, but I was quite surprised to see that it actually works, so I thought it may be worth sharing it:
let inline ctor< ^R, ^T
when ^R : (static member ``.ctor`` : ^T -> ^R)> (arg:^T) =
(^R : (static member ``.ctor`` : ^T -> ^R) arg)
This defines a function that will be inlined at compile time, which requires that the first type parameter has a constructor that takes a value of the second type parameter. This is specified as a compile-time constraint (because .NET generics cannot express this). Also, F# doesn't allow you to specify this using the usual syntax for specifying constructor constraints (which must take unit
as the argument), but you can use the compiled name of constructors. Now you can write for example:
// just like 'new System.Random(10)'
let rnd = ctor<System.Random, _> 10
rnd.Next(10)
And you can also use the result of ctor
as first-class function:
let chars = [ 'a'; 'b'; 'c' ]
let str = chars |> Array.ofSeq |> ctor<System.String, _>
As I said, I think this is mainly a curiosity, but a pretty interesting one :-).