2011-09-04 13 views
15

Me gustaría crear un nuevo tipo integral que esté limitado a un cierto rango. He tratado:Cómo crear un tipo delimitado dentro de un cierto rango

data PitchClass = PC Int deriving (Ord, Eq, Show) 

instance Bounded PitchClass where 
    minBound = PC 0 
    maxBound = PC 11 

Sin embargo, lo que quiero es algo que va a fallar si algo así como

PC 12 

o

PC (-1) 

se intenta.

Es el enfoque general para una situación en la que desea establecer restricciones para crear nuevos tipos uno en el que los constructores de valores no se exportan desde el módulo, sino funciones que devuelven instancias del tipo y que realizan comprobaciones de restricciones. ¿exportado?

Respuesta

14

Sí, no exportar el constructor de datos del módulo es el camino a seguir.

En su lugar, exporta una función que hace la comprobación como usted dijo. Esto a menudo se llama smart constructor.

5

Una solución alternativa para casos en los que el número total de valores es tan pequeño es simplemente enumerar los posibles constructores.

data PitchClass = A | Bb | B | C | Db | D | Eb | E | F | Gb | G | Ab 
    deriving (Eq, Ord, Bounded, Show, Read) 

Hay media docena diferentes hacks que puede probar aquí para hacerlo más conveniente de varias maneras; por ejemplo, puede derivar Enum para obtener toEnum . fromEnum = id (y toEnum (-1) = {- an exception -}), o puede escribir una instancia personalizada Integral para obtener 0 = A (y su elección de comportamiento para -1).

Cuestiones relacionadas