Haskell - MonadState

Haskell - MonadState

所以我最近一直在研究状态单子,因为我想在 haskell 中构建一个解析器组合器库。

我遇到了一个名为 MonadState 的类型类,我想知道这个类型类有什么意义,你会在哪里使用它?

MonadState 抽象状态 monad(好像这东西还不够抽象,对吧?)。它不需要具体类型 StateMonad 实例,它允许我们使用任何我们喜欢的 Monad,只要我们可以提供适当的 getput 函数.特别是,我们可以使用 StateT 来组合效果。

结合State和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)

MonadState 抽象出 getput 函数,因此它们不仅适用于一种类型,而且适用于 any 类型可以充当状态单子。它主要是为了让 monad 转换器工作。

无需过多介绍,我们假设您知道 StateT 存在:它需要一个 monad 和 returns 一个可以充当状态的新 monad。 (在这里我将忽略惰性和严格状态 monad 之间的区别)。然后可以通过将 StateT 应用于 Identity monad 来定义处理状态的 monad:

newtype State s = StateT s Identity

只要输入类型是monad,我们就可以为StateT:

返回的monad提供一个MonadState实例
-- Add state to any monad
instance Monad m => MonadState s (StateT s m) where
    ...

这表示将 StateT 应用于 any monad(而不仅仅是 Identity)会产生一个可以被视为状态 monad 的 monad。

此外,你可以说任何包装状态单子的东西也是状态单子,只要它实现了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
    ...