2017-08-20 40 views
2

我試圖將一個(ExceptT Error IO Foo)「semilift」到一個(ExceptT Error (StateT Bar IO) Baz)添加一個monad到變壓器堆棧的中間

我試過lift,fmap liftfmap return,沒有工作;這裏有一個標準成語嗎?

> 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

我認爲你正在尋找['mapExceptT'(https://開頭hackage。 haskell.org/package/transformers-0.5.4.0/docs/Control-Monad-Trans-Except.html#v:mapExceptT),但您的具體示例很難遵循。 – Alec

+0

另請參見第[2]節中的[提升以修復單體變壓器堆棧的內部](https://stackoverflow.com/a/27206159/791604)。也許這個問題是那個問題的重複。 –

回答

5

忽略ExceptT newtypes,你有

IO (Either Error Foo) 

而你要

StateT Bar IO (Either Error Foo) 

(我不知道你想什麼Baz,所以我忽略它。 )

那只是lift。所以,我相信你應該能夠使用

ExceptT . lift . runExceptT 

由於Alec noted,這可以使用mapExceptT這樣寫:

mapExceptT lift 
+0

啊,謝謝!我知道這很簡單... –