2012-10-07 10 views
20

Esta función:Num vs Integral

hola :: (Integral a) => a -> String 
hola 1 = "OK" 
hola _ = "asdf" 

funciona bien. Pero éste:

hola :: (Num a) => a -> String 
hola 1 = "OK" 
hola _ = "asdf" 

no puede ser compilado: "No se ha podido deducir (Eq a) que se deriven de lo literal` 1' "

realmente no lo entiendo. Estoy leyendo un tutorial donde se dice

"integral es también una clase de tipos numéricos. Num incluye todos los números, incluyendo los números reales y números enteros, Integral incluye sólo números enteros (integrales). En esta clase de tipos son Int y Entero." http://learnyouahaskell.com/types-and-typeclasses

¿Por qué no puedo utilizar Num?

Respuesta

27

Es un cambio reciente proposed and accepted in September/October last year, en la última versión del paquete base, Eq y Show ya no son superclases de Num. Desde ese cambio, no se ha publicado una nueva versión del informe de idioma, por lo que aún no figura en el informe. Y dado que es reciente, tampoco lo ha convertido en muchos tutoriales o libros.

La "coincidencia de patrón" con un literal numérico es una aplicación implícita de (==), por lo que se requiere una instancia Eq para que funcione. Esa instancia ahora ya no se puede deducir de la restricción Num, por lo que el compilador (bastante nuevo: D) rechaza el código con solo una restricción Num.

Pero Integral es una subclase de Real, que tiene Ord (y por lo tanto Eq) como una superclase, de ahí que funciona.

+0

Trabajando en la versión anterior :) ¡Gracias! Creo que este cambio hace que este lenguaje sea un poco confuso ... :( – user1726613

+0

Bueno, sin duda causará mucha confusión (y rotura de paquetes) en el período de transición. Pero el consenso general fue que la ganancia es mayor que la pérdida (no más instancias falsas de 'Eq' y 'Show' para cosas como funciones que pueden tener instancias 'Num' sensibles, excepto para los viejos requisitos' Eq' y 'Show'. Lo mismo (mutatis mutandis) se aplica a la eliminación de' Num' superclase de 'Bits'. Afortunadamente, las roturas son _backward-compatiblemente_ fijas agregando las restricciones. –

+0

Muchas gracias Daniel, sus respuestas fueron muy útiles. Así que con el nuevo compilador debo asegurarme de que la restricción incluya una ecuación instancia al menos para hacer la comparación. – user1726613

4

Como dijo Daniel Fischer, que solía trabajar, pero ahora no funciona porque Num y Eq se dividieron de manera Num a no implica Eq a más. Para corregir su código simplemente haga Eq a explícito:

hola :: (Num a, Eq a) => a -> String 
hola 1 = "OK" 
hola _ = "asdf" 
Cuestiones relacionadas