2010-10-13 3 views
64

Dans quelles situations faut-il utiliser liftIO? Lorsque j'utilise ErrorT String IO, la fonction lift fonctionne pour lever les actions E/S en ErrorT, donc liftIO semble superflu.Haskell: ascenseur vs liftIO

Répondre

75

lift lève toujours de la couche "précédente". Si vous devez soulever de la deuxième couche, vous auriez besoin de lift . lift et ainsi de suite. D'autre part, liftIO se lève toujours de la couche IO (qui, lorsqu'elle est présente, est toujours au bas de la pile). Donc, si vous avez plus de 2 couches de monades, vous apprécierez liftIO.

Comparer le type de l'argument dans les lambdas suivants:.

type T = ReaderT Int (WriterT String IO) Bool 

> :t \x -> (lift x :: T) 
\x -> (lift x :: T) :: WriterT String IO Bool -> T 

> :t \x -> (liftIO x :: T) 
\x -> (liftIO x :: T) :: IO Bool -> T 
+26

J'utiliserai généralement 'liftIO' pour soulever la couche IO même si' lift 'est suffisant, car alors je peux changer la pile monad et le code fonctionne toujours. –

+11

@John: bon point. Et aussi, il est évident que vous soulevez des E/S et pas n'importe quelle autre monade. –

28

liftIO est juste un raccourci vers l'IO Monad, selon que vous êtes dans le Monad Fondamentalement, liftIO équivaut à utiliser un nombre variable d'ascenseurs . Au premier abord, cela peut sembler redondant, mais utiliser liftIO a un grand avantage: il rend votre code IO indépendant de la construction réelle de Monad pour que vous puissiez réutiliser le même code quel que soit le nombre de couches de votre Monad final. lors de l'écriture d'un transformateur monad). D'autre part, liftIO ne vient pas gratuitement, comme le fait l'ascenseur: les transformateurs Monad que vous utilisez doivent avoir un support pour cela, par ex. La Monade dans laquelle vous êtes doit être une instance de la classe MonadIO, mais de nos jours la plupart des Monades (et bien sûr, le vérificateur de type vérifiera cela pour vous au moment de la compilation: c'est la force de Haskell!).