2017-08-20 8 views
2

J'essaie de "semilift" un (ExceptT Error IO Foo) à un (ExceptT Error (StateT Bar IO) Baz). J'ai essayé lift, fmap lift et fmap return, et aucun ne fonctionne; Y a-t-il un idiome standard ici?Ajouter une monade au milieu d'une pile de transformateurs

> import Control.Monad.Except 
> import Control.Monad.State 
> data Error 
> data Foo 
> data Bar 
> data Baz 
> x = undefined :: ExceptT Error IO Foo 
> y = undefined :: (ExceptT Error (StateT Bar IO) Baz) -> a 

> f = ??? -- This is what I'm trying to find. 

> :t y (f x) 
y (f x) :: a 
+1

Je pense que vous cherchez [ 'mapExceptT'] (https: // hackage. haskell.org/package/transformers-0.5.4.0/docs/Control-Monad-Trans-Except.html#v:mapExceptT), mais votre exemple concret est difficile à suivre. – Alec

+0

Voir aussi le point (2) à [Soulever pour fixer l'intérieur d'une pile de transformateurs monad] (https://stackoverflow.com/a/27206159/791604). Peut-être que cette question est une copie de celle-là. –

Répondre

5

Ignorant les ExceptT newtypes, vous avez

IO (Either Error Foo) 

Et vous voulez

StateT Bar IO (Either Error Foo) 

(je ne vois pas ce que vous voulez avec Baz, donc je suis ignorant.

C'est juste lift. Donc, je crois que vous devriez être en mesure d'utiliser

ExceptT . lift . runExceptT 

Comme Alec noted, cela peut être écrit en utilisant mapExceptT:

mapExceptT lift 
+0

Ah, merci! Je savais que c'était quelque chose de simple ... –