これはもう少し長くなるはずです。mtl、reader、exceptt&stacking order
calledFunction
:: (MonadReader env m, HasToken env, MonadIO m)
=> m (Either MyError MyResult)
calledFunction2
:: (MonadReader env m, HasToken env, MonadIO m)
=> m (Either MyError MyResult2)
:良いニュースは、私は質問の下部のコードサンプルを持っていること、考えはちょうどそれが
&エレガントな:-)を構築することですされた私のようなシグネチャを持つ関数のカップルを持っています
そして最後に、ExceptT String IO MyResult3
の結果を得たいと思っています。MyResult
& MyResult2
のようになります。
ExceptT :: m (Either e a) -> ExceptT e m a
そして私はちょうどEitherT calledFunction
を入力し、私はもうm (Either MyError MyResult)
が、ストレートExceptT MyError m MyResult)
を持っていません。
は、今では私が活用できるのでcalledFunction
がEither
を返すことは非常にうれしいです。進捗!
しかし、私はまた、calledFunction
に必要な読者のコンテキストを与える必要があります。さて、私はrunReaderT
でそれを行うだろう。私は今... ..だから、ExceptT MyError (ReaderT Config IO) MyResult
m
がどこにあるので、当然ReaderT
は行くべき、ExceptT MyError m MyResult
トランススタックになってきた
変圧器スタックの底部にありますか?私はトップレベルで読者を持つようにスタックを逆にあれば、そのrunReaderT
は自然に来るが、私は私のエレガントExceptT
でEither
...
import Control.Monad.Reader
import Control.Monad.Trans.Reader
import Control.Monad.Trans.Except
import Control.Monad.IO.Class
import Control.Error -- 'error' package
class HasToken a where
getToken :: a -> String
data Config = Config String
instance HasToken Config where
getToken (Config x) = x
data MyError = MyError String deriving Show
data MyResult = MyResult String
data MyResult2 = MyResult2 String
data MyResult3 = MyResult3 MyResult MyResult2
calledFunction
:: (MonadReader env m, HasToken env, MonadIO m)
=> m (Either MyError MyResult)
calledFunction = undefined
calledFunction2
:: (MonadReader env m, HasToken env, MonadIO m)
=> m (Either MyError MyResult2)
calledFunction2 = undefined
cfg = Config "test"
main = undefined
test :: ExceptT MyError IO MyResult3
test = do
-- calling runReaderT each time defeats the purpose..
r1 <- ExceptT (runReaderT calledFunction cfg)
r2 <- ExceptT (runReaderT calledFunction2 cfg)
return $ MyResult3 r1 r2
test1 = runReaderT test2 cfg
test2 :: ReaderT Config (ExceptT MyError IO) MyResult3
test2 = do
-- how to make this compile?
let cfg = Config "test"
r1 <- ExceptT calledFunction
r2 <- ExceptT calledFunction2
return $ MyResult3 r1 r2
右に、これは動作します:
ExceptT
コンストラクタで結果をラップ 'テスト=ホイスト(フリップrunReaderTのCFG)$やります...'。ありがとうございました! –