Haskell - MonadState

时间:2016-08-24 13:22:37

标签: haskell monads monad-transformers

所以我最近一直在关注状态monad,因为我想在haskell中构建一个解析器组合库。

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

2 个答案:

答案 0 :(得分:2)

MonadState抽象出getput函数,这样它们不仅可以用于一种类型,还可用于任何类型的函数,它们可以充当状态单子。它主要是为了使monad变换器工作。

不要过多详细说明,让我们假设您知道StateT存在:它需要一个monad并返回一个可以充当状态的新monad。 (我会忽略懒惰和严格状态monad之间的区别)。然后可以通过将StateT应用于Identity monad来定义处理状态的monad:

newtype State s = StateT s Identity

只要输入类型是monad,我们就可以为MonadState返回的monad提供StateT实例:

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

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

此外,您可以说包装状态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
    ...

答案 1 :(得分:0)

MonadState抽象状态monad(好像这些东西不够抽象,对吧?)。我们可以提供适当的StateMonad函数,而不是要求具有Monad实例的具体类型get,它允许我们使用我们喜欢的任何put 。特别是,我们可以使用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)