2

I'm trying to "semilift" an (ExceptT Error IO Foo) to an (ExceptT Error (StateT Bar IO) Baz).

I've tried lift, fmap lift, and fmap return, and none work; is there a standard idiom here?

> 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
Nathan Ringo
  • 973
  • 2
  • 10
  • 30
  • 1
    I think you are looking for [`mapExceptT`](https://hackage.haskell.org/package/transformers-0.5.4.0/docs/Control-Monad-Trans-Except.html#v:mapExceptT), but your concrete example is difficult to follow. – Alec Aug 20 '17 at 21:37
  • See also point (2) at [Lift to fix the inside of a monad transformer stack](https://stackoverflow.com/a/27206159/791604). Perhaps this question is a duplicate of that one. – Daniel Wagner Aug 21 '17 at 05:10

1 Answers1

5

Ignoring the ExceptT newtypes, you have

IO (Either Error Foo)

And you want

StateT Bar IO (Either Error Foo)

(I don't see what you want with Baz, so I'm ignoring it.)

That is just lift. So I believe you should be able to use

ExceptT . lift . runExceptT

As Alec noted, this can be written using mapExceptT:

mapExceptT lift
dfeuer
  • 48,079
  • 5
  • 63
  • 167