search
LoginSignup
0
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

逆状態モナド

逆状態モナド

 Stateモナドは、Haskellの遅延評価とmodifyの前後で状態の型が変わらない性質のおかげで、値の伝わり方の順序を保ちつつ状態の伝わり方を逆順にした派生を作ることができる。

newtype Rstate s a = Rstate { runRstate :: s -> (a, s) }

instance Functor (Rstate s) where
    fmap = liftM

instance Applicative (Rstate s) where
    pure = return
    (<*>) = ap

instance Monad (Rstate s) where
    return = Rstate . (,)
    x >>= f = Rstate $ \s0 ->
        let (a, s2) = runRstate x s1
            (b, s1) = runRstate (f a) s0
         in (b, s2)

instance MonadState s (Rstate s) where
    state = Rstate

 まあそうなるだろうなという感じで動く。

>>> flip runRstate "" $ do
>>>     modify (<> "Hello")
>>>     modify (<> "World")
>>>     modify (<> "!!!!!")
((),"!!!!!WorldHello")

 ちょっと面白けど、そんなに奇妙な動きをしているわけではない。

おまけ

 RstateT的なモナドトランスフォーマーを作ることはできない。これはモナドのバインドでは前の束縛を参照することができないからだ。

instance Monad m => Monad (RstateT m s) where
    x >>= f = RstateT $ \s0 -> do
        (a, s2) <- runRstateT x s1    -- ここでs1が見えない
        (b, s1) <- runRstateT (f a) s0
        return (b, s2)

 do構文を脱糖すれば、なぜ遅延評価をもってしても変数が見えないのかが分かる。

Rstate $ \s0 ->
    runRstateT x s1 >>= \(a, s2) ->    -- ここでs1が見えない
        runRstateT (f a) s0 >>= \(b, s1) ->
            return (b, s2)

 Rstateが実装できてRstateTが実装できないのは妙な気がするので、どうにか工夫すれば実装できそうな気がしないでもない。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0
Help us understand the problem. What are the problem?