下面是haskellbook中的代码片段,它一步一步地展示了monad转换器将如何展开:
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.如何解决这个问题?
发布于 2017-09-25 10:30:11
GHC型孔洞延伸到救援!它允许您在表达式中的某个位置设置一个_,并让GHC告诉您所需的类型。所以,让我们从
:t MaybeT (ExceptT (ReaderT (const _)))
<interactive>:1:33: error:
* Found hole: _ :: m (Either e (Maybe a))现在我们需要一个ReaderT () (Either e (Maybe a))值。水管_一遍又一遍,我们终于得到了价值
embedded = MaybeT (ExceptT (ReaderT (const (return (Right (Just 1))))))发布于 2017-09-25 10:27:22
您已经定义了一个MaybeT (ExceptT String (Reader ())) Int。你错过了最里面的一层,IO。与其他不同的是,IO没有具体的表示,但是您当然可以使用return或pure (duh)将纯值注入其中。
embedded' = MaybeT . ExceptT . ReaderT
$ (pure .) . const . Right $ Just 1https://stackoverflow.com/questions/46400679
复制相似问题