¿Cómo puedo hacer esto haskell en F # limpiamente?Versión F # de la coincidencia del patrón de haskell
add 1 2 x = 3 + x
add 1 x y = 1 + x + y
add z x y = z + x + y
¿Cómo puedo hacer esto haskell en F # limpiamente?Versión F # de la coincidencia del patrón de haskell
add 1 2 x = 3 + x
add 1 x y = 1 + x + y
add z x y = z + x + y
No se puede sobrecargar la función en sí, pero se puede utilizar directamente coincidencia de patrones:
let add z x y = // curried multiple parameters
match z, x, y with // convert to three-tuple to match on
| 1, 2, x -> 3 + x
| 1, x, y -> 1 + x + y
| z, x, y -> z + x + y
uso es el esperado: add 1 2 3
Si usted está dispuesto a utilizar tuplas como argumentos (es decir, renunciar a currying y aplicación parcial), incluso puede escribirlo más abreviado:
let add = // expect three-tuple as first (and only) parameter
function // use that one value directly to match on
| 1, 2, x -> 3 + x
| 1, x, y -> 1 + x + y
| z, x, y -> z + x + y
Uso actual es: add (1, 2, 3)
¡Gracias! Estaba buscando ejemplos de coincidencia de patrones f # en todas partes y nadie estaba haciendo coincidir más de un parámetro en muestras. Me dieron la impresión de que no podía hacer esto. –
@Jimmy: Técnicamente se está haciendo coincidir una sola tupla aquí, por lo que no te equivocaste ... – ildjarn
@ildjarn: solo en el segundo ejemplo que no es el que usaría porque pierde la aplicación currying/parcial que creo que es una de las partes más beneficiosas de estos idiomas –
Recall en Haskell que el general form of functions como una lista de declaraciones con patrones:
f pat1 ... = e1
f pat2 ... = e2
f pat3 ... = e3
es el azúcar sólo para el análisis case
:
f x1 .. xn = case (x1, .. xn) of
(pat1, ..., patn) -> e1
(pat2, ..., patn) -> e2
(pat3, ..., patn) -> e3
por lo la misma traducción se puede hacer a otros idiomas con coincidencia de patrones pero sin patrones de nivel de declaración.
Me doy cuenta que es solo un caso, pero la razón por la cual el azúcar existe en Haskell es por limpieza, esperaba que existiera algo similar en f #, y como yamen señaló, la coincidencia en f # puede funcionar de la misma manera –
Esto es puramente sintáctico. Lenguajes como Haskell, ML estándar y Mathematica le permiten escribir a cabo diferentes casos los partidos como si fueran diferentes funciones:
factorial 0 = 1
factorial 1 = 1
factorial n = n * factorial(n-1)
mientras que las lenguas como OCaml y F # requieren que usted tenga una única definición de la función y el uso de match
o su equivalente en su cuerpo:
let factorial = function
| 0 -> 1
| 1 -> 1
| n -> n * factorial(n-1)
tenga en cuenta que no tiene que copiar el nombre de la función una y otra vez, con esta sintaxis y se puede factorizar los casos de los partidos más fácilmente:
let factorial = function
| 0 | 1 -> 1
| n -> n * factorial(n-1)
Como yamen escribió, haz currying con let f a b = match a, b with ...
en F #.
En la implementación árbol rojo-negro clásico, creo que la duplicación de los nombres de las funciones y los lados derechos de Standard ML y Haskell bastante feas:
balance :: RB a -> a -> RB a -> RB a
balance (T R a x b) y (T R c z d) = T R (T B a x b) y (T B c z d)
balance (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d)
balance (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d)
balance a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d)
balance a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d)
balance a x b = T B a x b
en comparación con el equivalente OCaml o F #:
let balance = function
| B, z, (T(R, y, T(R, x, a, b), c) | T(R, x, a, T(R, y, b, c))), d
| B, x, a, (T(R, z, T(R, y, b, c), d) | T(R, y, b, T(R, z, c, d))) ->
T(R, y, T(B, x, a, b), T(B, z, c, d))
| a, b, c, d -> T(a, b, c, d)
No conozco a Haskell, ¿cuál es el objetivo aquí? Esto parece una optimización que el compilador captará y resolverá. Creo que tratar de escribir un equivalente en F # con la coincidencia de patrones sería más lento. ¿Qué estás intentando lograr? – gjvdkamp
gjvdkamp, no es una optimización, es un dispositivo sintáctico que hace que cada caso sea más fácil de leer. 'f 1 = x; f 2 = y' se traduce a 'f a = caso a de 1 -> x; 2 -> y' - http://www.haskell.org/onlinereport/decls.html#sect4.4.3.1 –