抽象構文木のダンプ準備(代数的データ型の出力練習)


Verilogパーサで生成した抽象構文木のダンプ準備として
代数的データ型を出力するコードで感じをみてみました。


webで読むことのできる Real World Haskellベータ版の
JSONデータを操作する章を参考にしました。
Chapter 5. Writing a library: working with JSON data


いまは変更されて無くなっていますが
以前はこの章に forM_ を使ったサンプルがありました。
forM_ に慣れておきたいので、練習では使ってみています。

$ cat DumpTest.hs

module DumpTest where

import Control.Monad(forM_)

data Foo = FStr String
         | FInt Integer
         | FBool Bool
         | FNil
         | FObj [(String, Foo)]
         | FBar Bar
         deriving (Show)

data Bar = BStr String
         | BInt Integer
           deriving (Show)

printBar :: Bar -> IO ()
printBar (BStr s) = putStrLn $ show s
printBar (BInt i) = putStrLn $ show i

printValue :: Foo -> IO ()
printValue (FBar f) = printBar f
printValue (FStr s) = putStrLn $ show s
printValue (FInt i) = putStrLn $ show i
printValue (FBool True) = putStrLn "true"
printValue (FBool False) = putStrLn "false"
printValue FNil = putStrLn "nil"
printValue (FObj xs) = do
    putStr "{ "   
    case xs of
        [] -> putStrLn ""
        (p:ps) -> do putPair p
                     forM_ ps $ \q -> do putStr ", "
                                         putPair q
    putStrLn "}"
        where
            putPair (k, v) = do putStr $ show k
                                putStr ": "
                                printValue v

-- test data
dat :: Foo
dat = FObj ([("a", FInt 10), ("b", FStr "foo"),
            ("c", FNil), ("d", FBool True), ("e", FBool False),
            ("f", FBar (BStr "bar"))])


ghciで動作確認です。

$ ghci
GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.

Prelude> :l DumpTest
[1 of 1] Compiling DumpTest         ( DumpTest.hs, interpreted )
Ok, modules loaded: DumpTest.

*DumpTest> printValue dat
{ "a": 10
, "b": "foo"
, "c": nil
, "d": true
, "e": false
, "f": "bar"
}


あと、putStrとか putStrLnしているところを
ファイルI/O処理にしてファイルに書き出します。
というか JSONとか YAMLとかにしてしまえばよいかな?と思っていたり。