Pregunta

Me preguntaba si es posible hacer coincidir contra los mismos valores para múltiples veces con el patrón de instalaciones de lenguajes de programación funcional (Haskell / F # / Caml). A juego

Basta pensar en el siguiente ejemplo:

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

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

Una aplicación más útil sería esto (simplificar una AST).

simplify (Add a a) = Mult 2 a

Pero Haskell rechaza estos códigos y me advierte de conflictivas definiciones 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 Quiero encontrar equivalencias en las que ocurrirá varias veces?

¿Fue útil?

Solución

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

http://www.mail-archive.com/ haskell-cafe@haskell.org/msg59617.html

http://www.mail-archive.com/ haskell-cafe@haskell.org/msg62491.html

En pocas palabras:. No es imposible de implementar, pero se decidió en contra por motivos de simplicidad

Por cierto, que no necesitan if o case para evitar este; la forma (un poco) mejor es utilizar un guardia:

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

Otros consejos

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

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

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

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é un "patrón" tal, no tendría mucho sentido en general: lo Si a es una función ? (Es imposible, en general, para verificar que dos funciones son iguales.)

Haskell no hace unificación.

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)]}))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top