stringf is an F# function that invokes any ToString(string) method.

F# comes with the built-in string function, which is essentially an adapter over Object.ToString. That often comes in handy, because it lets you compose functions without having to resort to lambda expressions all the time.

Instead of writing this (to produce the string "A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z"):

['A' .. 'Z'] |> (fun x -> x.ToString()) |> String.concat ", "

You can write this:

['A' .. 'Z'] |> string |> String.concat ", "

That's nice, but some .NET types provide an overloaded ToString function taking a format string as argument:

and so on.

While these methods can be useful, it would be nice to be able to use them as functions, like the string function. The problem, it seems, is that this ToString overload is part of no interface or base class.

Statically typed duck typing

That's not a problem for F#, because it enables us to do statically typed duck typing!

In this case, you can define a stringf function:

let inline stringf format (x : ^a) = 
    (^a : (member ToString : string -> string) (x, format))

You can use the function like this:

> DateTimeOffset.Now |> stringf "o";;
val it : string = "2015-05-07T14:24:09.8422893+02:00"
> DateTimeOffset.Now |> stringf "T";;
val it : string = "14:24:18"
> DateTime.Now |> stringf "t";;
val it : string = "14:24"
> TimeSpan.FromDays 42. |> stringf "c";;
val it : string = "42.00:00:00"
> 0.42m |> stringf "p0";;
val it : string = "42 %"

Perhaps it would be better to define more domain-specific functions like percent, roundTrippable, time, etc., but it's interesting that such a function as stringf is possible.

Wish to comment?

You can add a comment to this post by sending me a pull request. Alternatively, you can discuss this post on Twitter or Google Plus, or somewhere else with a permalink. Ping me with the link, and I may add it as a comment.


Friday, 08 May 2015 05:40:00 UTC


"Our team wholeheartedly endorses Mark. His expert service provides tremendous value."
Hire me!