Pregunta Reescritura de Erlang en F #


He encontrado un presentación por Don Syme, que muestra que Erlang

fac(0) -> 1
fac(N) -> N * fac(N-1).

es equivalente a F # 's

let rec fac = function
| 0 -> 1
| n -> n * fac (n-1)

Pero parece que no hay forma de utilizar la coincidencia de patrones para una aridad diferente sin perder la seguridad del tipo. P.ej. uno podría usar una coincidencia de patrón de lista, pero luego un tipo debe ser un tipo base común (como object)

let concat = function
    | [x;y] -> x.ToString() + y.ToString()
    | [x] -> x.ToString()

Dado que las funciones F # en los módulos no admiten sobrecargas, parece que la única manera de reescribir el código Erlang en F # con el tipado estático es utilizar clases estáticas con sobrecarga de métodos en lugar de módulos. ¿Hay una mejor manera de reescribir las funciones de Erlang con diferente arity en F #?

En general, ¿es correcto decir que la coincidencia de argumentos de Erlang es más cercana a la sobrecarga de métodos de .NET (incluyendo C #) que a la coincidencia de patrones de F #? O no hay un reemplazo directo entre los dos, por ejemplo. Podría haber una función en Erlang con diferentes aridades + un guardia:

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.

En el último caso los argumentos son de diferentes tipos. ¿Cómo lo reescribirías en F #?


6
2018-03-23 09:03


origen


Respuestas:


Puede lograr algo cercano a la sobrecarga repensando el problema ligeramente. En lugar de pensar en el función como el eje de la variabilidad, piense en la entrada como la parte variable. Si haces eso, te darás cuenta de que puedes lograr lo mismo con una unión discriminada.

Aquí hay un ejemplo más artificial que el del artículo vinculado:

type MyArguments = One of int | Two of int * int

let foo = function
    | One x -> string x
    | Two (x, y) -> sprintf "%i%i" x y

Uso:

> foo (One 42);;
val it : string = "42"
> foo (Two (13, 37));;
val it : string = "1337"

Obviamente, en lugar de definir un tipo tan 'estúpido' como el anterior MyArguments, definirías una unión discriminada que tiene sentido en el dominio que estás modelando.


7
2018-03-23 09:23