5
class Monad m => MonadState s m | m -> s where
    -- | Return the state from the internals of the monad.
    get :: m s
    get = state (\s -> (s, s))

    -- | Replace the state inside the monad.
    put :: s -> m ()
    put s = state (\_ -> ((), s))

    -- | Embed a simple state action into the monad.
    state :: (s -> (a, s)) -> m a
    state f = do
      s <- get
      let ~(a, s') = f s
      put s'
      return a

instance MonadState s m => MonadState s (MaybeT m) where...

MonadState のインスタンスが状態とモナドを必要とするのはなぜですか?単一のパラメーター State クラスを作成しないのはなぜですか?

4

2 に答える 2

6

かなり異なる質問なので、コメントでGertの質問に答えてみてください。

問題は、なぜ私たちはただ書くことができないのかということです

class State s where
   get :: s
   put :: s -> ()

さて、これを書くことができます。しかし今問題は、それで何ができるかということです。そして難しいのは、put xand then laterを使用したコードがある場合get、 を にリンクしgetて、put入れたものと同じ値が返されるようにするにはどうすればよいかということです。

そして問題は、タイプ()とだけsでは、一方を他方にリンクする方法がないことです。さまざまな方法で実装を試みることができますが、うまくいきません。putデータを からに運ぶ方法はありgetません (誰かがこれをよりよく説明できるかもしれませんが、理解するための最良の方法は、それを書いてみることです)。

>>モナドは、操作をリンク可能にする唯一の方法であるとは限りませんが、 2 つのステートメントをリンクする演算子を持っているため、1 つの方法です。

(>>) :: m a -> m b -> m b

だから私たちは書くことができます

(put x) >> get

編集:これは、パッケージで定義されたインスタンスを使用した例ですStateT

foo :: StateT Int IO ()
foo = do
    put 3
    x <- get
    lift $ print x

main = evalStateT foo 0
于 2012-09-02T18:19:23.263 に答える
4

状態のタイプをモナドのタイプに関連付ける何らかの方法が必要です。MultiParamTypeClasseswithFunctionalDependenciesは1つの方法です。ただし、を使用して実行することもできますTypeFamilies

class (Monad m) => MonadState m where
    type StateType m

    -- | Return the state from the internals of the monad.
    get :: m (StateType m)
    get = state (\s -> (s, s))

    -- | Replace the state inside the monad.
    put :: StateType m -> m ()
    put s = state (\_ -> ((), s))

    -- | Embed a simple state action into the monad.
    state :: (StateType m -> (a, StateType m)) -> m a
    state f = do
      s <- get
      let ~(a, s') = f s
      put s'
      return a

instance MonadState m => MonadState (MaybeT m) where
    type StateType (MaybeT m) = StateType m

    ...

これは、 monads-tfパッケージで採用されているアプローチです。

于 2012-09-02T17:09:30.480 に答える