2012-04-11 8 views
5

Recientemente he estado tratando de "aprenderme un Haskell" y me gustaría crear un nuevo tipo para representar un estado entero, sin solo usar un entero en bruto (para seguridad de tipo y claridad de código). En concreto, el siguiente código compila:¿Por qué un tipo Haskell "derivado integral" necesita estar "derivando Enum"?

newtype AuxState = AuxState Integer 
    deriving (Eq, Ord, Num, Integral, Real, Enum) 

Sin embargo, puesto que hay un número infinito de estados en mi solicitud, no tengo ningún interés en convertir este estado en una enumeración. Sin embargo, si trato de quitar la instrucción deriving (Enum) lo que es sólo deriving (Eq, Ord, Num, Integral, Real), el compilador se queja:

No instance for (Enum AuxState) 
    arising from the 'deriving' clause of a data type declaration 
Possible fix: 
    add an instance declaration for (Enum AuxState) 
    or use a standalone 'deriving instance' declaration, 
     so you can specify the instance context yourself 
When deriving the instance for (Integral AuxState) 

Me resulta difícil creer que Haskell obliga a un tipo en la clase Integral estar también en la clase de enumeración; ¿No debería ser al revés? ¿Hay alguna razón para esto, o estoy haciendo/entendiendo algo mal?

+2

Las instancias Enum son tipos ordenados secuencialmente, sus valores se pueden enumerar. La principal ventaja de la clase de tipo Enum es que podemos usar sus valores en rangos de lista. También tienen sucesores y predecesores definidos, que podemos obtener con las funciones y predicciones. Creo que todos los enteros deberían pertenecer a esta clase, ¿por qué no deberían ser los tuyos? –

+1

"Sin embargo, dado que hay una cantidad infinita de estados en mi aplicación, ..." Creo que tiene un entendimiento erróneo de 'Enum'. 'Enum' no significa un tipo con un número finito de valores. – newacct

+1

"¿No debería ser al revés?" 'Double' es un' Enum', pero obviamente no 'Integral' – newacct

Respuesta

8

Todo Integral son necesariamente Enum porque los cimientos de Integral matemáticas son las succ y pred operaciones. (Técnicamente, Enum representa una jerarquía de tipos adecuada, donde un tipo Integral es un semigrupo matemático, creo). A la inversa, parece aún más erróneo: ¿quiere decir que cada Enum debería ser ? ¿Esto incluye ADT aleatorios como

data Foo = A | B | C | D | E | F | G deriving (Enum) 

?

(Cada Enum debería ser isomorfo a un subconjunto de Integral, sin duda, pero que en realidad sugiere que va la otra dirección: Integral puede representar cualquier Enum pero no al revés, por lo Integral es una especie de la UR Enum.)

+0

No diría 'Integral' es un semigrupo. Es una especie de dominio euclidiano (es decir, una buena variedad de anillo) pero con algunas restricciones adicionales. –

6

La razón técnica es que se debe a Integral se define en Prelude de la siguiente manera:

class (Real a, Enum a) => Integral a where 
    ... 

La razón matemática es que cada tipo integral es enumerable, pero sin t viceversa Piensa en los números racionales, por ejemplo. Tenga en cuenta que Enum no implica enumeración finita como se muestra en Integer.

Cuestiones relacionadas