2011-10-26 14 views
5

Así que tener un tipo de datos algo así como:prueba si la variable Haskell coincide con la opción de tipo de datos definido por el usuario

data Token = NUM Int | ID String | EOF 

y tengo una función algo así como:

doStuff list = let 
     (token, rest) = getToken list 
    in 
     .... 

Así que lo que quiero hacer en la parte ... es prueba si el token que obtuve es un NUM o INT o EOF. Puedo decir token==EOF para probar ese caso, pero no puedo encontrar una manera de probar si el token es NUM o INT usando un condicional, ya que token==(NUM n) y token==NUM ambos producen errores. Sé que podría escribir una función auxiliar para hacer las cosas en el ... y aprovechar la coincidencia de patrones, pero eso realmente daña la legibilidad de lo que estoy haciendo, y parece que debería haber una forma de hacer este control. Alguien sabe como?

Respuesta

12

¿Quieres una case expresión, como:

case token of 
    NUM n -> foo n 
    ID s -> bar s 
    _  -> hoho 

Ese es el mismo tipo de coincidencia de patrones que se obtendría si ha definido una función por separado.

8

Un truco lindo para esto es usar sintaxis de registro. La ventaja de este enfoque es que sigue funcionando incluso si cambia el número de argumentos de un constructor en particular. Tenga en cuenta que el tipo de datos en sí no necesita ser declarado usando la sintaxis del registro para aprovechar este truco.

case token of 
    NUM {} -> ... 
    ID {} -> ... 
    EOF {} -> ... 
+0

¿Cómo se obtienen los valores? Parece que los tiras aquí ... – mergeconflict

+0

@mergeconflict Si quieres los valores, no usas este truco, por supuesto. =) Pero sonaba a la pregunta como si solo quisiera verificar qué constructor se usó. –

+0

@mergeconflict puede obtener selectivamente los valores de esta manera: 'data Token = NUM ​​{n, m :: Int}' --- 'case tokenVal of Num {n = n '} -> foo n'' –

Cuestiones relacionadas