2011-05-11 8 views
8

Supongamos que tengo una expresión Haskell como:patrón de juego Haskell casos simétricos

foo (Nothing, Just a) = bar a 
foo (Just a, Nothing) = bar a 

¿Hay alguna sintaxis de Haskell a colapsar esos casos, por lo que puede coincidir con cualquiera de patrón y especificar bar a como la respuesta para ambos? ¿O es tan breve como puedo obtenerlo?

+0

Véase también http://stackoverflow.com/questions/5914965/patterns-for-symmetric-functions – kennytm

Respuesta

5

que es tan breve como se pone en Haskell. En ML hay una sintaxis para lo que quiere (escribiendo varios patrones, que se unen las mismas variables, al lado del otro separados por | con el cuerpo después de que el último patrón), pero en Haskell no lo hay.

8

Si su código es más complejo que el ejemplo, puede hacer algo como esto, usando la instancia Alternative para Maybe y la extensión PatternGuards (parte de Haskell2010).

{-# LANGUAGE PatternGuards #-} 
import Control.Applicative 

foo (x, y) | Just a <- y <|> x = bar a 

En caso de que no están familiarizados con ella <|>, picos más a la izquierda Just si hay uno y devuelve Nothing lo contrario, haciendo que el patrón de guardia falle.

+2

una importante advertencia sin embargo - esto coincide con más casos que el original código. foo (Just x, Just y) se emparejaría, así que si eso no es lo que quieres, tendrás que asegurarte de manejarlo en un caso anterior. – mokus

4

Puede utilizar -XViewPatterns, añadir funciones arbitrarias a colapsar sus dos casos en un único patrón. Su patrón es ahora una función p que produce la cosa que desea hacer coincidir:

foo (p -> (Just a, Nothing)) = bar a 

mucho más simple!

tenemos que definir p aunque, como:

p (Nothing, [email protected](Just _)) = (a, Nothing) 
p [email protected](Just _, Nothing) = a 
p a      = a 

o como desee para normalizar los datos antes de ver.


Referencias: El GHC User's Guide chapter on View Patterns

Cuestiones relacionadas