Pourquoi n’y a-t-il pas de transformateur IO dans Haskell?

Toutes les autres monades sont livrées avec une version transformateur, et d’après ce que je sais, l’idée d’un transformateur est une extension générique des monades. Après la construction des autres transformateurs, IOT serait quelque chose comme

 newtype IOT ma = IOT { runIOT :: m (IO a) } 

pour lequel je pourrais inventer des applications utiles sur place: IOT MaybeIOT Maybe peut IOT Maybe il soit faire une action IO ou rien, IOT [] peut créer une liste qui pourra être sequence ultérieurement d.

Alors, pourquoi n’y a-t-il pas de transformateur IO dans Haskell?

(Notes: j’ai vu ce post sur Haskell Cafe , mais je ne peux pas le comprendre. En outre, la page Hackage du transformateur ST mentionne un problème potentiel dans sa description, mais n’offre aucun détail.)

Considérons l’exemple spécifique de IOT Maybe . Comment écririez-vous une instance Monad pour cela? Vous pourriez commencer avec quelque chose comme ceci:

 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 

Maintenant, vous avez m' :: IO (Maybe (IO b)) , mais vous avez besoin de quelque chose de type Maybe (IO b) , où – le plus important – le choix entre Just et Nothing doit être déterminé par m' . Comment cela serait-il mis en œuvre?

La réponse, bien sûr, est que ce ne serait pas le cas, car ce n’est pas possible. Vous ne pouvez pas non plus justifier un unsafePerformIO , caché derrière une interface pure, car fondamentalement vous demandez une valeur pure – le choix du constructeur Maybe – de dépendre du résultat de quelque chose dans IO . Nnnnnope, ça n’arrivera pas.

La situation est encore pire dans le cas général, car une Monad arbitraire (quantifiée universellement) est encore plus impossible à déployer IO .


Incidemment, le transformateur ST vous mentionnez est implémenté différemment de votre IOT suggéré. Il utilise l’implémentation interne de ST comme une monade de type State utilisant des primitives spéciales de poussière de lutin magiques fournies par le compilateur, et définit un transformateur semblable à StateT sur cette base. IO est implémenté en interne en tant que ST encore plus magique, et un IOT hypothétique pourrait donc être défini de manière similaire.

Non pas que cela change vraiment quelque chose, si ce n’est que vous avez peut-être un meilleur contrôle sur l’ordre relatif des effets secondaires impurs causés par les IOT .