19

Me preguntaba si es posible hacer coincidir los mismos valores para múltiples veces con las funciones de coincidencia de patrones de los lenguajes de programación funcionales (Haskell/F #/Caml).Patrón que coincide con los valores idénticos

sólo piensa en el siguiente ejemplo:

plus a a = 2 * a 
plus a b = a + b 

La primera variante se llamaría cuando se invoca la función con dos valores similares (que se almacenan en a).

Una aplicación más útil sería esta (simplificando un AST).

simplify (Add a a) = Mult 2 a 

Pero Haskell rechaza estos códigos y me advierte de definiciones en conflicto para a - Tengo que hacer comprueba si a caso explícito/en lugar de averiguar si la función tiene valores idénticos. ¿Hay algún truco para indicar que una variable con la que quiero hacer coincidir ocurrirá varias veces?

+0

FWIW, Mathematica admite esto. –

Respuesta

39

Esto se llama patrón no lineal. Ha habido varios hilos en la lista de correo de Haskell-Cafe sobre esto, no hace mucho tiempo. Éstos son dos:

http://www.mail-archive.com/[email protected]/msg59617.html

http://www.mail-archive.com/[email protected]/msg62491.html

En pocas palabras: no es imposible de implementar, pero se decidió en contra por motivos de simplicidad. Por supuesto, no necesita if o case para solucionar este problema; la forma (un poco) mejor es utilizar un guardia:

a `plus` b 
    | a == b = 2*a 
    | otherwise = a+b 
+0

Gracias por los enlaces - Excelente – Dario

13

No se puede tener dos parámetros con el mismo nombre para indicar que deben ser iguales, pero se puede usar para distinguir guards casos como éste:

plus a b 
    | a == b = 2 * a 
    | otherwise = a + b 

Esto es más flexible ya que también trabaja para condiciones más complicadas que la simple igualdad.

+0

Sí, conozco a los guardias, pero traté de evitar cualquier comparación manual. – Dario

+0

Un poco abreviado para esto: http: // stackoverflow.com/questions/480769/f-matching-with-two-values ​​/ 501541 # 501541 – Dario

-1

Haskell no hace unificación.

+4

Necesitaría variables libres en ambos lados para la unificación. –

+1

Esto es solo igualdad, no unificación. Me gusta '| a, a cuando a = a -> ..'. –

0

Acabo de ver los hilos de listas de correo que figuran en la respuesta de Thomas, y la primera respuesta en uno de ellos tiene sentido, y explica por qué tales un "patrón" no tendría mucho sentido en general: ¿qué ocurre si a es una función? (Es imposible en general comprobar que dos funciones son iguales.)

+0

¿No podría simplemente limitar 'a' para ser' Eq'? – gdejohn

+0

@gdejohn, sospecho que la semántica no estaría bien. Al aplicar una definición de la forma 'fxx = x', se podría esperar razonablemente IMO que los dos argumentos presentados sean * el mismo valor *, y no solo" igual "en el sentido de alguna clase de letra (de lo contrario, ni siquiera está claro qué de los dos valores de 'x' debería' f' regresar). – Alexey

-1

He implementado un nuevo lenguaje de programación funcional que puede manejar patrones no lineales en Haskell.

https://github.com/egison/egison

En mi idioma, su función en plus escrito de la siguiente manera.

(define $plus 
    (match-lambda [integer integer] 
    {[[$a ,a] (* a 2)] 
    [[$a $b] (+ a b)]})) 
Cuestiones relacionadas