programming plataforma pagina online oficial mac descargar compiler haskell ghci

plataforma - haskell website



GHCi ignora la firma del tipo (2)

Prelude> let myprint = putStrLn . show Prelude> :t myprint myprint :: () -> IO ()

OK, nada demasiado inusual aquí. Solo las reglas predeterminadas de tipo GHCi, supongo ...

Prelude> let myprint = (putStrLn . show) :: Show x => x -> IO () Prelude> :t myprint myprint :: () -> IO ()

¿¿Que brujería es esta?? ¿Estás en un punto en blanco ignorando mi declaración de tipo? O_O

¿Hay alguna manera de convencer a GHCi para que haga lo que realmente quería?


Agregar una anotación de tipo a una expresión como en

e :: type

hace que el compilador compruebe que e tiene ese type , así como el uso de ese type para impulsar la creación de instancias de variables de tipo y la selección de instancias. Sin embargo , si el type es polimórfico, aún se puede crear una instancia más adelante. Considerar por ejemplo

(id :: a -> a) "hello"

Anteriormente, se creará una instancia de String , a pesar de mi anotación. Promover,

foo :: Int -> Int foo = (id :: a -> a)

hará a instancia para ser instanciada a Int más adelante. La anotación anterior de id no da ninguna información a GHC: ya sabe que id tiene ese tipo. Podríamos eliminarlo sin afectar la comprobación de tipo en absoluto. Es decir, las expresiones id e id :: a->a no solo son dinámicamente equivalentes, sino también estáticamente similares.

Del mismo modo, las expresiones.

putStrLn . show

y

(putStrLn . show) :: Show x => x -> IO ()

son estáticamente equivalentes: solo estamos anotando el código con el tipo que GHC puede inferir. En otras palabras, no estamos proporcionando ninguna información a GHC que aún no conozca.

Una vez que se verifica el tipo de anotación, GHC puede crear una instancia de x más. La restricción de monomorfismo hace eso en tu ejemplo. Para evitar eso, use una anotación para el enlace que está introduciendo, no para la expresión :

myprint :: Show x => x -> IO () myprint = (putStrLn . show)


Podemos hacer lo siguiente, con restricción de monomorfismo en:

>let myprint :: Show x => x -> IO (); myprint = putStrLn . show >:t myprint myprint :: Show x => x -> IO ()

Esto no es lo mismo que let myprint = putStrLn . show :: Show x => x -> IO () let myprint = putStrLn . show :: Show x => x -> IO () . En el primer caso tenemos un enlace con una firma de tipo, en el último caso tenemos un enlace con una anotación de tipo en el lado derecho. El monomorfismo verifica las firmas de tipo de nivel superior, pero no las anotaciones locales.