08

30

[Haskell] Haskellで 状態マシンを書く

2012.08.30(22:50)

Haskellで状態マシンを書いてみました。

states.png
普通の信号機です。(また信号機かよ)。C言語では状態もカウンタも変数ですが、変数を使わない Haskellでも状態マシンが書けます。

{-# OPTIONS -Wall -Werror #-}

-- 定数
initialCount :: Int
initialCount = 3

-- 状態
data Color = Green | Yellow | Red deriving (Show)

-- 信号機
data Signal = Signal {
   count :: Int
  ,touch :: Int
  ,color :: Color
} deriving (Show)

-- 信号機の各状態から別の状態への遷移
updateSignal :: Color -> Signal -> Signal
updateSignal Red    s =
    s { color = Green, count = (count s)-1 }
updateSignal Green  s =
    s { color = Yellow }
updateSignal Yellow s =
    s { color = Red }

-- 信号機を1状態ずつ変化させる関数
runSignal :: Signal -> IO ()
runSignal s = do
                putStrLn $ show s
                let s1 = updateSignal (color s) s 
                let s2 = s1 { touch = (touch s) + 1} 
                if count s2 > 0
                  then runSignal s2
                  else return ()

-- メイン関数
main :: IO()
main = do
  putStrLn "Signal State Machine"
  runSignal Signal { count = initialCount
                    ,touch = 0
                    ,color = Green }
 

実行結果
*Main> :main
Signal State Machine
Signal {count = 3, touch = 0, color = Green}
Signal {count = 3, touch = 1, color = Yellow}
Signal {count = 3, touch = 2, color = Red}
Signal {count = 2, touch = 3, color = Green}
Signal {count = 2, touch = 4, color = Yellow}
Signal {count = 2, touch = 5, color = Red}
Signal {count = 1, touch = 6, color = Green}
Signal {count = 1, touch = 7, color = Yellow}
Signal {count = 1, touch = 8, color = Red}
it :: ()
 

これを種にしていろいろな状態マシンを作ってみることにします。
プロフィール

島敏博

Shima Toshihiro 島敏博
信州アルプスハイランド在住。HaskellとElixirが好き。組み込みソフトウェアアーキテクト、C++プログラマ、山歩き、美術館巡り、和食食べ歩き、日本赤十字社救急法指導員、インデックス投資、クラシック音楽、SESSAME会員、状態マシン設計、モデル駆動開発、ソフトウェアプロダクトライン、Rubyist、実践ビジネス英語

■ ツイッター
http://twitter.com/saltheads
■ Facebook
http://www.facebook.com/saltheads
■ Qiita
http://qiita.com/saltheads

印刷する場合は、ブラウザの印刷メニューではなく、このページの上から3cmくらいの青いところにある、「印刷」を押してみてください。少しうまく印刷できます。まだ完全ではないのですが、これで勘弁してください。


カテゴリ
最新記事
月別アーカイブ
最新コメント
検索フォーム
リンク
sessame
RSSリンクの表示