2

State モナドによく似たものを作成しようとしていますが、述語のリストとそれに伴う状態の遷移関数も保持しています。私が想定している計算の基本的な手順は次のとおりです。

Foo (state, [(pred, t)]) >>= f. に適用fs、降伏しs'ます。次に、各述語を に適用しますs'。一致する述語ごとに、関連付けられた遷移関数を順番に状態に適用します。たとえば[(p1, t1), (p2, t2), (p3, t3)]、 、f、およびと仮定しsます。after f syieldss'と両方の returnの場合、p1 s'yieldを実行してから、計算の結果であるyieldingを実行します。p3 s'Truet1 s's''t3 s''s'''

ここには多くの可動部分があり、これを StateT トランスフォーマーまたは State モナドの上に構築するのが正しいアプローチであるかのように感じますが、どこから始めればよいかわかりません。

これがどうもはっきりしないように感じます。これをより明確にする明確化は大歓迎です。

4

1 に答える 1

8

あなたが求めているモナドを作ることはできないと思います。jozefg との議論で述べたように、次の 2 つのモナド則があります。

f >=> return = f
return >=> f = f

これは、バインディングの場所で「興味深い」ことは何も起こらないことを意味します。特に、各バインディングで状態遷移関数を実行することはできません。なぜなら、f >=> returnその遷移関数を実行しても実行せfず、これらの法則が破られるからです。

しかし、だからといって、状態遷移を実行するモナド アクションを作成することを止めるわけではありません。そこで、このような遷移を追跡してオンデマンドで実行するモナドを設計する方法のアイデアをスケッチします。API を使いたい場合は、API を肉付けする必要があります。基本的な考え方は、s状態としてだけではなく、遷移テーブルと遷移テーブルの両方を格納するというものsです。まず、いくつかのボイラープレート。

{-# LANGUAGE FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses #-}
import Control.Arrow
import Control.Applicative
import Control.Monad.State

s -> sここでは、トランジションだけを扱いましょう。述語と遷移のリストを調べて、実行したいものを選択するなど、好きなように実装できます。しかし、それはアイデアの残りの部分を正しくすることと直交しています。Monad新しい型を定義し、基になる型にディスパッチするだけのインスタンスを与えます。

newtype TStateT s m a = TStateT { unTStateT :: StateT (s, s -> s) m a }
    deriving (Functor, Applicative, Monad)

このMonadStateインスタンスは、単に を使用するよりも少しトリッキーですderivingが、それでも非常に簡単です。おそらく公的には、それは国家の一部であると偽りたいと考えているsので、少し注意を向ける必要があります。また、アナログを与えてrunStateT、適切な初期遷移関数を選択します。(後でこの選択を変更する方法を示します。)

instance Monad m => MonadState s (TStateT s m) where
    state f = TStateT (state (\(s, t) -> let (v, s') = f s in (v, (s', t))))

runTStateT :: Functor m => TStateT s m a -> s -> m (a, s)
runTStateT m s = second fst <$> runStateT (unTStateT m) (s, id)

ここで、興味深いビットが来ます。の超能力はTStateT、いつでも実行できるいくつかの遷移があることです。そこで、それらを実行する方法と遷移表を変更する方法を提供しましょう。

step :: Monad m => TStateT s m ()
step = TStateT (gets snd) >>= modify

modifyTransitions :: Monad m => ((s -> s) -> (s -> s)) -> TStateT s m ()
modifyTransitions = TStateT . modify . second

そして、それはほとんどすべてです!

于 2013-10-21T02:38:04.980 に答える