Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?

More than 1 year has passed since last update.

@sparklingbaby

逆状態モナド

逆状態モナド

 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が実装できないのは妙な気がするので、どうにか工夫すれば実装できそうな気がしないでもない。

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What is going on with this article?