Pensé que, en principio, el sistema de tipo de haskell prohibiría llamar a funciones impuras (es decir, f :: a -> IO b
) de las puras, pero hoy me di cuenta de que al llamarlas con return
compilan muy bien. En el ejemplo:¿Cuál es el significado de las acciones de IO dentro de funciones puras?
h :: Maybe()
h = do
return $ putStrLn "???"
return()
Ahora, h
obras en la mónada tal vez, pero es una pura función, sin embargo. Compilarlo y ejecutarlo simplemente devuelve Just()
como uno esperaría, sin hacer ninguna E/S. Creo que la pereza de Haskell junta las cosas (es decir, el valor de retorno de putStrLn
no se usa, y no puede, ya que sus constructores de valores están ocultos y no puedo hacer coincidir el patrón), pero ¿por qué es legal este código? ¿Hay alguna otra razón que hace esto permitido?
Como extra, pregunta relacionada: en general, ¿es posible prohibir en absoluto la ejecución de acciones de una mónada desde otras? ¿Cómo?
¿Cómo puedo darle a una mónada la capacidad de ejecutar acciones desde otra, dándole la posibilidad de emparejar patrones con los valores que contiene? –
Escribiendo métodos que convierten una mónada en otra, o realizan alguna ejecución. 'Control.Monad.ST.stToIO' convierte un cálculo' ST' en un cómputo 'IO', por ejemplo. –
Cristalino. ¡Gracias a los dos! –