utiliza tipos tipo restricciones reales que multiples función funciones declarar como clase bounded haskell types

tipos - Haskell: YesNo tipo de clase. ¿Por qué Integer?



string en haskell (3)

Entonces, ¿esto significa que cuando escribo un número entero en GHCi, generalmente asume que su valor es Integer?

Sí. Básicamente, GHCi primero intentará con Integer , luego, si eso falla, Double y luego finally () para resolver restricciones de tipo ambiguas. Puede leer los detalles sobre cómo funciona esto en la Guía del usuario de GHC .

Sin embargo, tenga en cuenta que en los módulos compilados, las reglas son un poco más estrictas. En particular, la configuración predeterminada solo se aplica a las clases estándar, por lo que su ejemplo no funcionará sin una anotación de tipo en un módulo compilado a menos que habilite la extensión ExtendedDefaultRules que le brinda el mismo comportamiento que GHCi.

Tengo una pregunta sobre cómo GHCi asume el tipo de un número entero.

Estaba leyendo Sí-No tipo de clase de Learn you a Haskell.

Aquí hay un enlace si quieres leer todo. http://learnyouahaskell.com/making-our-own-types-and-typeclasses#a-yes-no-typeclass

Para decirlo brevemente, este capítulo muestra que al definir mi propia clase, puedo hacer una función que funcione con muchos tipos.

Este libro define la clase YesNo con una función.

yesno :: a -> Bool

y hacer Int como una instancia de clase YesNo

instance YesNo Int where yesno 0 = False yesno _ = True

Cuando cargué esto en mi GHCi y escribí

yesno 0

devolvió el error. Pensé que probablemente es porque GHCi no puede decir si 0 está destinado a ser Int Integer Double u otro tipo en la clase Num . En realidad, cuando escribí yesno (0 :: Int) funcionó.

Así que solo por diversión hice Integer como una instancia de la clase YesNo y escribí

instance YesNo Integer where yesno 0 = True yesno _ = False

(Note que volteé Verdadero y Falso) y otra vez, escribí

yesno 0

(Sin ninguna declaración de tipo), entonces GHCi mostró True .

Por otra parte, cuando escribí

yesno $ fromIntegral 0

devolvió True , lo que significa que GHCi piensa que el tipo de fromIntegral 0 es Integer .

Entonces, ¿esto significa que cuando escribo un número entero en GHCi, generalmente asume que su valor es Integer en lugar de? Estoy confundido porque :t 0 devuelve Num a => a


Es el tipo predeterminado junto con las reglas predeterminadas extendidas de ghci.

Los literales enteros son polimórficos, tienen el tipo Num a => a (ya que representan el fromInteger literal ). Pero cuando se evalúa una expresión, necesaria para imprimir su resultado, por ejemplo, la expresión debe recibir un tipo monomórfico.

Por sí mismo,

yesno 0

impone las dos restricciones Num a y YesNo a en el 0 , y toda la expresión tendría el tipo ambiguo

yesno 0 :: (Num a, YesNo a) => Bool

(Es ambiguo, ya que la variable de tipo en la restricción no es accesible desde el tipo a la derecha de => ).

En general, los tipos ambiguos son errores de tipo, sin embargo, en algunos casos, la ambigüedad se resuelve al crear una instancia de la variable de tipo restringido con un tipo predeterminado. Las reglas en la especificación de lenguaje son que una variable de tipo puede ser predeterminada si

En situaciones en las que se descubre un tipo ambiguo, una variable de tipo ambigua, v , es definible si:

- `v` appears only in constraints of the form `C v`, where `C` is a class, and - at least one of these classes is a numeric class, (that is, `Num` or a subclass of `Num`), and - all of these classes are defined in the Prelude or a standard library (Figures 6.2–6.3 show the numeric classes, and Figure 6.1 shows the classes defined in the Prelude.)

La restricción (Num a, YesNo a) cumple los dos primeros requisitos, pero no el tercero. Por lo tanto, según el estándar de idioma, no es predeterminado y debería ser un error de tipo.

Sin embargo, ghci usa reglas predeterminadas extendidas y también variables predeterminadas de tipo restringido por clases no definidas en Prelude o las bibliotecas estándar.

Entonces, aquí elegiría el valor predeterminado para una restricción Num , a menos que haya una declaración explícita predeterminada dentro del alcance, que sea Integer o, si Integer no satisface las restricciones, se intenta el Double .

Por lo tanto, cuando tenga una instance YesNo Integer , ghci puede predeterminar con éxito la variable de tipo a Integer . Pero sin una instancia de este tipo disponible, el incumplimiento falla porque ninguno de los candidatos predeterminados tiene una instancia.


en el primer caso intenta escribir:

Prelude> yesno (0 :: Int) False