I have found a presentation by Don Syme which shows that Erlang's
fac(0) -> 1
fac(N) -> N * fac(N-1).
is equivalent to F#'s
let rec fac = function
| 0 -> 1
| n -> n * fac (n-1)
But it looks like there is no way to use pattern matching for a different arity without losing type safety. E.g. one could use a list pattern matching, but then a type must be a common base type (such as object):
let concat = function
| [x;y] -> x.ToString() + y.ToString()
| [x] -> x.ToString()
Given that F# functions in modules do not support overloads, it looks like the only way to rewrite Erlang code into F# with static typing is to use static classes with method overloading instead of modules. Is there a better way to rewrite Erlang functions with different arity in F#?
In general, is it correct to say that Erlang's argument matching is closer to .NET's (including C#) method overloading rather than to F#'s pattern matching? Or there is no direct replacement between the two, e.g. there could be a function in Erlang with different arities + a guard:
max(x) -> x.
max(x,y) when x > y -> x.
max(x,y) -> y.
max(comparer, x, y) -> if comparer(x,y) > 0 -> x; true -> y end.
In the last case the arguments are of different types. How would you rewrite it in F#?