Rewriting Erlang in F#

Viewed 396

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#?

1 Answers
Related