dyayamlをHaskellにポートしてみた

本来の日本時間のエントリがエントリだけに一日進める。

シリアライズしたいだけならderived (Show, Read)で簡単に文字列化できるとか言うの禁止。

http://panathenaia.halfmoon.jp/alang/dyayaml.html

こんなデータ構造があったとします。

data Sample = Sample { a :: Integer, b :: [Integer] } 

要素のsetterを用意します。

set_a (Sample a b) value = Sample value b
set_b (Sample a b) value = Sample a value

シリアライズのために各要素をなめる関数を定義します。(Haskellだとここが短くなって嬉しい。Delphiだとこんな。DやAdaでも要トリックと正式な文法だけでいけるかの差はあっても記述量としてはDelphiの例と大差無し。)

sample_io = do 
  io "a" a set_a
  ioList "b" b set_b $ io_ 5

5は意味のないデフォルト値。
……便利な構文が……。sakuraiさんありがとうございます。というわけでsetter直書き。

sample_io = do 
  io "a" a (\ x v -> x { a = v })
  ioList "b" b (\ x v -> x { b = v }) io_ 5

あとはごにょにょ。

sampleYAML = writeYAML "sample" (ioMap_ sample_io) (Sample 1 [2, 3]) 
testW = putStr sampleYAML
testR = putStr $ show $ readYAML "sample" (ioMap_ sample_io) (Sample (0) []) sampleYAML

……で、確かに使えるのですが。

Text.YAML.DYAYaml> testW
--- !sample

a: 1
b:
	- 2
	- 3

Text.YAML.DYAYaml> parseYAML sampleYAML >>= putStr . show
("sample",[Element {name = "", kind = EnterMap, comment = ""},Element {name = "a
", kind = Value "1", comment = ""},Element {name = "b", kind = EnterList, commen
t = ""},Element {name = "", kind = Value "2", comment = ""},Element {name = "", 
kind = Value "3", comment = ""},Element {name = "", kind = Leave, comment = ""},
Element {name = "", kind = Leave, comment = ""},Element {name = "", kind = End, 
comment = ""}])
Text.YAML.DYAYaml> testR
Sample {a = 1, b = [2,3]}
Text.YAML.DYAYaml> 

YAMLUTF-8
Hugsはマニュアルにはlocale依存コードとUTF-16の間で変換を行ってくれると書かれているのですが、行ってくれていません。ということでASCIIしか通せず。そもそもSJISの'\'を含む文字列リテラルがエラーになるためどうするべきかわからず。
いや変換すりゃいいんですが手間がかかるようだとHaskellにする意味がないっつーかで放り投げ。
つーかHaskellでpeekなんとかって書いてると激しくCの方がマシ感に襲われるのでよくないです。

最終的に何がしたいかといいますと、「型付きのインタプリタで」簡単なゲームが作りたいのですが……Hugsは不向きっぽい。
要はStateモナドなのですが久しぶりなせいか実力のせいか(たぶん後者)、えらく手間が。