私は、そのノードがHaskellのコールスタックを持つ他のマシンになることができる状態マシンをモデル化しようとしています。そのノードが他のネストされたマシンになることができる状態マシンをエンコードする
module Cont (Cont(..)) where
data Cont where
-- continue in the same machine
Cont :: Show s => s -> Cont
-- fork a new machine
Start :: (Show s, Show s') => s -> s' -> Cont
-- final state
End :: Show s => s -> Cont
我々はどちらか
- 同じマシンに続行することができます:たとえば
Bar
についてはは
module Bar (BarState(..), run) where import Cont data BarState = BInit | BMid | BEnd deriving Show run BInit = Cont BMid run BMid = End BEnd
Cont
タイプは、状態遷移を説明することにより、符号化されている非常に単純なマシンですbyCont s
それだけで
- コール新しいマシン
Start s s'
- が
End s
Cont
と
End
を使用していますので
Bar
によって状態s
でマシンを終了しますが、他のフローを呼び出すことはありませんが、Foo
はへの呼び出しを行うマシンですBar
:
module Foo (FooState(..), run) where
import qualified Bar as Bar
import Cont
data FooState = FInit | FBar | FEnd deriving Show
run FInit = Start FBar Bar.BInit
run FBar = End FEnd
マシンはある時点で1つの状態にあり、どのマシンでも別のマシンを呼び出すことができます(Start s s'
)。私は状態のスタックと私の全体のユーザーの状態を説明します。
import qualified Bar as Bar
import qualified Foo as Foo
import Cont
data Stack s = Empty | s ::: Stack s ; infixr 5 :::
data States = FooState Foo.FooState | BarState Bar.BarState
run :: Stack States -> Stack States
run Empty = error "Empty stack"
run (s ::: rest) = proceed (run' s) rest
run' :: States -> Cont
run' (FooState s) = Foo.run s
run' (BarState s) = Bar.run s
proceed :: Cont -> Stack States -> Stack States
proceed (Cont s) rest = undefined ::: rest
proceed (Start s s') rest = undefined ::: undefined ::: rest
proceed (End s) rest = rest
問題は、私はs
Cont
でコンストラクタのパターンマッチではないということです。
私の最終目標は、任意の有効な状態からのフローを続けることを可能にする直列化可能スタックを持つことです。例:
run [FInit] -> [BInit, FInit]
run [BInit, FInit] -> [BEnd, FInit]
run [BMid, FInit] -> [BEnd, FInit]
run [BEnd, FInit] -> [FEnd]
この例のモジュールのソースコードはhereです。
このモデルをエンコードするには、より良い方法があるかもしれませんが、私は私のものに限定されません。