2010-02-20 28 views
5

Tengo una función haskell que calcula el tamaño de la lista de Ints finitos. Necesito el tipo de salida a ser un número entero, porque el valor será en realidad mayor que el máximo unido de Int (el resultado será -1 para ser exactos si el tipo de salida es un Int)Haskell Error: No se pudo encontrar el tipo esperado "Integer" contra el tipo inferido `Int '

size :: a -> Integer 
size a = (maxBound::Int) - (minBound::Int) 

entiendo la diferencia entre Ints (acotado) e Integers (ilimitado) pero me gustaría hacer un Integer a partir de un Int. Me preguntaba si había una función como la de Entero, que me permitiría convertir un tipo Int a Integer.

+0

No usaste 'a'. – kennytm

+0

(en re. @dons última pregunta :) Por "tamaño de la lista de Ints finitos" ¿te refieres a los elementos numéricos que estarían en una lista que contiene todos los posibles Ints? – MtnViewMark

+0

@KennyTM, sí, lo sé :) La función de tamaño es propiedad de un tipo de clase finita que está sobrecargado para subtipos separados (int, producto de finitos, etc. por lo que 'a' se utiliza para desviar la sobrecarga para usar – Fry

Respuesta

11

Tendrá que convertir los valores en números enteros, los cuales se pueden hacer por la función fromIntegral (fundición numérico para Haskell):

fromIntegral :: (Integral a, Num b) => a -> b 

Convierte cualquier tipo en la clase integral de cualquier tipo en el (más grande) Num clase. P.ej.

fromIntegral (maxBound::Int) - fromIntegral (minBound::Int) 

Sin embargo, realmente no confío en el enfoque que está tomando, parece muy frágil. El comportamiento en presencia de tipos que admiten envolvente es bastante sospechoso.

A qué te refieres con: "el tamaño de la lista de Ints finitos". ¿Cuál es el tamaño en este sentido, si no es la longitud de la lista?

+0

Sí, es en esencia la longitud de la lista, pero incluso una lista limitada puede ser grande. Entonces, para obtener la longitud de una lista, primero tendría que construir la lista y luego intentarlo. De esta forma puedo simplemente generar la respuesta sin generar toda la lista :) – Fry

4

Te creo buscas:

fromIntegral :: (Integral a, Num b) => a -> b 

que convertirá un entero a un Int

+0

... y viceversa. (es decir, convertir una Int en un Entero) – BMeph

0

Tal vez asumían que Haskell, como muchos idiomas corriente principal como C y (hasta cierto extensión) Java, tiene coacciones numéricas implícitas. No lo hace: Int e Integer son tipos totalmente no relacionados y existe una función especial para convertir entre ellos: fromIntegral. Pertenece a la clase de tipo Num. Mire la documentación: esencialmente, desde Integral hace más que eso: es un genérico "construir la representación de un número integral arbitrario", t.i. si está implementando algún tipo de número e instanciando Num, debe proporcionar una forma de construir números enteros de su tipo. Por ejemplo, en la instancia Num para números complejos, fromIntegral crea un número complejo con una parte imaginaria cero y una parte real integral.

El único sentido en que Haskell tiene coacciones numéricas implícitas es que los literales enteros están sobrecargados, y cuando se escribe 42, el compilador lo interpreta implícitamente como "fromIntegral (42 :: Integer)", por lo que puede usar enteros en cualquier contextos donde se requiere un tipo Num.

+0

Lamento ser un nítido (pero como toca uno de mis problemas con la clase Num "pila", me complaceré ...) pero desde el tipo 'Complex a' (qué , ¿no es una clase? ¿Es esa una de esas "optimizaciones prematuras"?) tiene un contexto 'RealFloat a', tu número Complex integrado no tendrá una parte real integral, sino uno 'Real', muy probablemente un Double. Aparte de esa pequeña objeción, esa es una respuesta bastante buena, ¡continúa! – BMeph

Cuestiones relacionadas