¿Por qué no hay transformador IO en Haskell?
monads monad-transformers (1)
Cada otra mónada viene con una versión de transformador, y por lo que sé, la idea de un transformador es una extensión genérica de las mónadas. Siguiendo con la construcción de los otros transformadores, IOT
sería algo así como
newtype IOT m a = IOT { runIOT :: m (IO a) }
para lo cual pude inventar aplicaciones útiles sobre el terreno: IOT Maybe
puede hacer una acción IO o nada, IOT []
puede construir una lista que luego puede ser la sequence
d.
Entonces, ¿por qué no hay transformador IO en Haskell?
(Notas: He visto esta publicación en Haskell Cafe , pero no puedo darle mucho sentido. Además, la página de Hackage para el transformador ST menciona un problema posiblemente relacionado en su descripción, pero no ofrece ningún detalle).
Considere el ejemplo específico de IOT Maybe
. ¿Cómo escribirías una instancia de Monad
para eso? Puedes comenzar con algo como esto:
instance Monad (IOT Maybe) where
return x = IOT (Just (return x))
IOT Nothing >>= _ = IOT Nothing
IOT (Just m) >>= k = IOT $ error "what now?"
where m'' = liftM (runIOT . k) m
Ahora tiene m'' :: IO (Maybe (IO b))
, pero necesita algo de tipo Maybe (IO b)
, donde, lo más importante, la elección entre Just
y Nothing
debería estar determinada por m''
. ¿Cómo se implementaría eso?
La respuesta, por supuesto, es que no lo haría, porque no puede. Tampoco puede justificar una forma de unsafePerformIO
allí, escondida detrás de una interfaz pura, porque, fundamentalmente, está pidiendo un valor puro (la elección de Maybe
constructor) para depender del resultado de algo en IO
. Nnnnnope, no va a suceder.
La situación es aún peor en el caso general, porque una Monad
arbitraria (universalmente cuantificada) es aún más imposible de desenrollar que IO
.
Por cierto, el transformador ST
que menciona se implementa de forma diferente a su IOT
sugerida. Utiliza la implementación interna de ST
como una mónada similar a State
utilizando primitivas especiales de polvo mágico mágico proporcionadas por el compilador, y define un transformador tipo StateT
basado en eso. IO
se implementa internamente como un ST
aún más mágico, por lo que un IOT
hipotético podría definirse de manera similar.
No es que esto realmente cambie nada, aparte de posiblemente darle un mejor control sobre el orden relativo de los efectos secundarios impuros causados por IOT
.