mar*_*ngw 4 haskell typeclass monad-transformers
我正在尝试构建一个MaybeT-Transformer Monad,基于真实世界Haskell,Monad变换器章节中的示例:
data MaybeT m a = MaybeT { runMT :: m (Maybe a) }
instance (Monad m) => Monad (MaybeT m) where
m >>= f = MaybeT $ do a <- runMT m
case a of
Just x -> runMT (f x)
Nothing -> return Nothing
return a = MaybeT $ return (Just a)
instance MonadTrans MaybeT where
lift m = MaybeT $ do
a <- m
return (Just a)
Run Code Online (Sandbox Code Playgroud)
这很好,但现在我想让MaybeT成为MonadWriter的一个实例:
instance (MonadWriter w m) => MonadWriter w (MaybeT m) where
tell = lift . tell
listen m = MaybeT $ do unwrapped <- listen (runMT m)
return (Just unwrapped)
Run Code Online (Sandbox Code Playgroud)
该告诉是好的,但我不能让听功能权限.在构造函数折纸的1 1/2天后我能想出的最好的是你在上面看到的那个:unwrapped应该是(也许是a,w)的元组,并且我想要包含在Maybe-Type中并把整个东西放在一个空的MonadWriter中.
但编译器抱怨:
Occurs check: cannot construct the infinite type: a = Maybe a
When generalising the type(s) for `listen'
In the instance declaration for `MonadWriter w (MaybeT m)'
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
listen 有类型签名
m a -> m (a, w)
Run Code Online (Sandbox Code Playgroud)
即
MaybeT m a -> MaybeT m (a, w)
Run Code Online (Sandbox Code Playgroud)
但MaybeT $ listen (runMT m) >>= return . Just有类型签名
MaybeT m a -> MaybeT m (Maybe a, w)
Run Code Online (Sandbox Code Playgroud)
所以引发了无限类型错误.您需要将其转换unwrapped :: (Maybe a, w)为a Maybe (a, w)才能继续:
listen m = MaybeT $ do (val, wr) <- listen (runMT m)
case val of
Nothing -> return Nothing
Just x -> return (Just (x, wr))
Run Code Online (Sandbox Code Playgroud)
(顺便说一句,在http://www.haskell.org/haskellwiki/New_monads/MaybeT中有一个MaybeT的实现.)
| 归档时间: |
|
| 查看次数: |
547 次 |
| 最近记录: |