2016-08-24 40 views
-1

所以我最近一直在寻找状态monads,因为我想在haskell中构建解析器组合器库。Haskell - MonadState

我遇到了一个叫做MonadState的类型类,我想知道这个类型类的什么地方,你会在哪里使用它?

+0

'MonadState'是单子类型类如'国':https://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-State-Class.html –

+0

你做了什么研究来自己回答这个问题?您是否阅读过文档?你是否使用了'MonadState'? –

回答

2

MonadState抽象出getput功能,使他们无法正常工作只为一种类型,但对于任何类型,它可以作为一个国家单子行动。这主要是为了让单子变压器工作。

不用过多的细节,我们假设你知道StateT存在:它需要一个monad并返回一个可以充当状态的新monad。 (我会忽略懒惰和严格的国家monads之间的区别)。一个处理状态A单子然后可以通过施加StateTIdentity单子来定义:

newtype State s = StateT s Identity 

只要输入类型是单子,我们可以通过StateT返回的单子提供MonadState实例

-- Add state to any monad 
instance Monad m => MonadState s (StateT s m) where 
    ... 

这就是说施加到StateT任何单子(不只是Identity)产生可被视为状态单子一个单子。

此外,你可以说,任何包装的状态单子也是一种境界单子,只要它实现MonadState

-- Add Maybe to a state monad, it's still a state monad 
instance MonadState s m => MonadState s (MaybeT m) where 
    ... 

-- Add Writer to a state monad, it's still a state monad 
instance (Monoid w, MonadState s m) => MonadState s (WriterT w m) where 
    ... 
0

MonadState摘要状态monad(就好像这个东西不够抽象吧?)。如果我们可以提供适当的getput函数,它可以让我们使用我们喜欢的任何Monad,而不需要具体类型StateMonad实例。特别是,我们可以使用StateT这让我们结合起来。

简单的例子,结合国家和IO:

tick :: (MonadIO m, MonadState Int m) => m() 
tick = do 
    x <- get 
    liftIO $ putStrLn ("incrementing " ++ (show x)) 
    put (x+1) 

> runStateT (tick >> tick >> tick >> tick) 5 
incrementing 5 
incrementing 6 
incrementing 7 
incrementing 8 
((),9)