2012-06-12 7 views
21

Estoy aprendiendo Haskell, y estaba jugando en ghci cuando me encontré con algo muy desconcertante.¿Qué está pasando con los tipos en esta sesión de ghci?

En primer lugar, crear una función de complemento simple:

Prelude> let add x y = x + y 

Tenga en cuenta que funciona con enteros y flota:

Prelude> add 3 4 
7 
Prelude> add 2.5 1.3 
3.8 

A continuación, cree una función de aplicación. Es idéntico al $ (pero no infijo). Funciona como un no-op en el complemento:

Prelude> let apply f x = f x 
Prelude> apply add 3 4 
7 
Prelude> apply add 2.5 1.3 
3.8 

Ok, ahora hacen add' que es el mismo que add' pero utilizando apply:

Prelude> let add' = apply add 
Prelude> add' 3 4 
7 
Prelude> add' 2.5 1.3 

<interactive>:1:9: 
    No instance for (Fractional Integer) 
     arising from the literal `1.3' at <interactive>:1:9-11 
    Possible fix: add an instance declaration for (Fractional Integer) 
    In the second argument of `add'', namely `1.3' 
    In the expression: add' 2.5 1.3 
    In the definition of `it': it = add' 2.5 1.3 

Wat.

Éstos son los tipos:

Prelude> :t add 
add :: (Num a) => a -> a -> a 
Prelude> :t apply add 
apply add :: (Num t) => t -> t -> t 
Prelude> :t add' 
add' :: Integer -> Integer -> Integer 
Prelude> 

¿Por qué add' tener un tipo diferente de apply add?

¿Es esta una rareza ghci, o es esto cierto en Haskell en general? (¿Y cómo puedo saber la diferencia?)

+13

Tan pronto como escuché "estaba jugando en ghci y vi algo extraño", creo que "restricción de monomorfismo" – amindfv

Respuesta

18

Es el Monomorphism restriction. Cuando define un valor con un enlace de patrón simple (solo el nombre, sin ningún argumento de función) y sin una firma de tipo, obtiene un tipo monomórfico. Cualquier variable de tipo es tratada para ser desambiguada de acuerdo con defaulting rules, si eso no funciona, obtendrá un error de tipo.

En este caso, la variable de tipo constreñida Num se establece de manera predeterminada en Integer.

Puede desactivar la restricción monomorphism con

ghci> :set -XNoMonomorphismRestriction 

o con la bandera -XnoMonomorphismRestriction en la línea de comandos.

Cuestiones relacionadas