48 votes

Pourquoi n'y a-t-il pas de transformateur IO en Haskell?

Chaque autre monade est livrée 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. Suivant la manière dont les autres transformateurs sont construits, IOT serait quelque chose comme

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

pour lequel je pourrais inventer des applications utiles sur le moment : IOT Maybe peut soit effectuer une action IO, soit rien, IOT [] peut construire une liste qui peut ensuite être séquencée.

Alors pourquoi n'y a-t-il pas de transformateur IO en Haskell ?

(Remarques : j'ai vu ce post sur Haskell Cafe, mais je n'arrive pas à en faire beaucoup de sens. De plus, la page Hackage pour le transformateur ST mentionne un problème potentiellement lié dans sa description, mais n'offre aucun détail.)

37voto

C. A. McCann Points 56834

Considérez l'exemple spécifique de IOT Maybe. Comment écririez-vous une instance de Monad pour cela? Vous pourriez commencer par 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

Vous avez maintenant 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 devrait être déterminé par m'. Comment cela serait-il implémenté?

La réponse, bien sûr, est que cela ne serait pas fait, car cela ne peut pas l'être. Vous ne pouvez pas non plus justifier un unsafePerformIO là-dedans, 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, cela n'arrivera pas.

La situation est encore pire dans le cas général, car un Monad arbitraire (quantifié universellement) est encore plus impossible à défaire que IO ne l'est.


À propos, le transformateur ST que vous mentionnez est implémenté différemment de votre IOT suggéré. Il utilise l'implémentation interne de ST comme un monade de type State utilisant des primitives spéciales fournies par le compilateur, et définit un transformateur de type StateT basé sur cela. IO est implémenté internalement de manière encore plus magique que ST, et donc un hypothétique IOT pourrait être défini de manière similaire.

Non que cela ne change vraiment quelque chose, à part peut-être vous donner un meilleur contrôle sur l'ordre relatif des effets secondaires impurs causés par IOT.

3voto

Roman Cheplyaka Points 15145

J'ai écrit un article sur les transformateurs de monades – cela répond également à votre question (recherchez IOT).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X