Clojureでステートマシン書いてみたのでメモ

おもちゃ未満ながら、Clojureでステートマシン書いてみたのでメモ。
(2013/12/16 微編集)

コード

(def states-def
  "状態定義"
  {:state01                               ;状態ID
     [[#(println "->state01")]            ;上記状態に到達した際に評価される関数のベクタ
      {:event01                           ;イベントID
         [[#(println "event01 happened!")];上記状態で上記イベントが発生した際に評価される関数のベクタ
          :state02]}]                     ;次の状態のID 

   :state02              
     [[#(println "->state02")] 
      {:event02                
         [[#(println "event02 happened!")] 
          :state01]}]})           

(defn happen-event!
  "イベント発生"
  [state event & param]
  (let [[event-acts next-state] (event (second (state states-def)))
        next-state-acts         (first (next-state states-def))]
    (dorun (map #(%) event-acts))
    (dorun (map #(%) next-state-acts))
    next-state))

実行例

state.core=> (happen-event! (happen-event! :state01 :event01) :event02)

event01 happened!
->state02
event02 happened!
->state01
:state01


state.core=> (-> :state01 (happen-event! :event01)
                          (happen-event! :event02))

event01 happened!
->state02
event02 happened!
->state01
:state01