2017-09-25 14 views
1

私はステップバイステップを示しhaskellbookからコードスニペットを以下、どのようにモナド変圧器をアンラップしようとしていますどのようにまとめますか?

module OuterInner where 

    import Control.Monad.Trans.Except 
    import Control.Monad.Trans.Maybe 
    import Control.Monad.Trans.Reader 

    -- We only need to use return once 
    -- because it's one big Monad 
    embedded :: MaybeT (ExceptT String (ReaderT() IO)) Int 
    embedded = return 1 

    maybeUnwrap :: ExceptT String (ReaderT() IO) (Maybe Int) 
    maybeUnwrap = runMaybeT embedded 

    -- Next 
    eitherUnwrap :: ReaderT() IO (Either String (Maybe Int)) 
    eitherUnwrap = runExceptT maybeUnwrap 

    -- Lastly 
    readerUnwrap ::() -> IO (Either String (Maybe Int)) 
    readerUnwrap = runReaderT eitherUnwrap 

運動は、私は再びすべてをラップする持っていること、あります:

embedded :: MaybeT (ExceptT String (ReaderT() IO)) Int 
embedded = ??? (const (Right (Just 1))) 

次のように私が試した:

embedded' :: MaybeT (ExceptT String (ReaderT() IO)) Int 
embedded' = MaybeT (ExceptT (ReaderT (const (Right (Just 1))))) 

をしかし、コンパイラは文句:

D:\haskell\chapter26\src\OuterInner.hs:24:15: error: 
    * Couldn't match type `Either a0' with `IO' 
     Expected type: MaybeT (ExceptT String (ReaderT() IO)) Int 
     Actual type: MaybeT (ExceptT String (ReaderT() (Either a0))) Int 
    * In the expression: 
     MaybeT (ExceptT (ReaderT (const (Right (Just 1))))) 
     In an equation for embedded': 
      embedded' = MaybeT (ExceptT (ReaderT (const (Right (Just 1))))) 

D:\haskell\chapter26\src\OuterInner.hs:24:32: error: 
    * Couldn't match type `Maybe Integer' 
        with `Either String (Maybe Int)' 
     Expected type: ReaderT() (Either a0) (Either String (Maybe Int)) 
     Actual type: ReaderT() (Either a0) (Maybe Integer) 
    * In the first argument of `ExceptT', namely 
     `(ReaderT (const (Right (Just 1))))' 
     In the first argument of `MaybeT', namely 
     `(ExceptT (ReaderT (const (Right (Just 1)))))' 
     In the expression: 
     MaybeT (ExceptT (ReaderT (const (Right (Just 1))))) 
Failed, modules loaded: none. 

どのように運動を解決するには?

答えて

5

救助者へのGHC型付き穴拡張!式のどこかに_を繋ぎ、GHCに必要なタイプを伝えるようにします。だから、今、私たちはReaderT() (Either e (Maybe a))の値を必要とするのは、

:t MaybeT (ExceptT (ReaderT (const _))) 

<interactive>:1:33: error: 
    * Found hole: _ :: m (Either e (Maybe a)) 

から始めましょう。配管_私たちは最終的に値段で到着します。

embedded = MaybeT (ExceptT (ReaderT (const (return (Right (Just 1)))))) 
+0

「GHCタイプの穴が救助者に拡張されました」とはどういう意味ですか? –

+1

ええと。 Chip&Daleのように。あなたを助けるために来る。 – arrowd

+0

式のどこにでも_を配置します。それは仕様によると無効な識別子なので、とにかくエラーになります。 GHCはそのタイプを推論する自由をとり、そのエラーを引き起こす前にそのタイプを出力します。あなたは式を構築し、あなたが不明な場所に_を置いて、次に、あなたは曖昧な意味で型をコードに書き込ませます。 – HTNW

5

MaybeT (ExceptT String (Reader())) Intを定義しました。あなたは最奥のレイヤー、IOが欠けています。他のものとは異なり、IOには具体的な表現はありませんが、純粋な値をreturnまたはpure(duh)で注入することはもちろん可能です。

embedded' = MaybeT . ExceptT . ReaderT 
      $ (pure .) . const . Right $ Just 1 
関連する問題