週に一回は書きますよ 月に4つ記事を書けばノルマは満たされます。
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

ゲームを作るためにステートマシンを振り回しつつ、ふと気になったことがあります。 参照透過な言語で入出力を行うのにすぐ思いつくのはWorld型との相互作用を書くこと ですが、Haskellはモナドを用いることでもっときれいに入出力が書けます。 たしかこのような説明がどこかにあったような。 ステートマシンの更新もWorldの書き換えと似たようなものなので、これも実は モナドでかけるのではないでしょうか。

当面のプログラムはステートマシンで書くとして、そういうものも探しておいて 損は無い、むしろHaskellの書き方を学ぶ上で広く役立つかもしれない、と思いました。 そのような情報はおそらくhaskell.orgに行けば多くあるのかもしれません。 とりあえず私は手近なところ、tanakhさんの日記のコメントで言及されていた "The Yampa Arcade" を読んでみました。

いきなりArrowですよArrow。 正直判らないので、Arrow Circuit 1 by oxyさんを読んで勉強しました。 とりあえず(->)やKleisli arrowsの定義を読んで、計算途中に文字列を書き出すArrowを作ったんですが、失敗しました。結果しか出てきません。

--前略 orGateやandGateは上記の引用もとと同様のものを用いる
--計算ついでに文字を出力するArrow
type IOArrow = Kleisli IO
fun2IOA :: Show b => String -> (b->c) -> IOArrow b c
fun2IOA name fn = proc b -> do
	c <- (arr fn) -< b
	_ <- (arr $ putStrLn . (name++) . show) -< b
	returnA -< c

nameIOA :: Show b => String -> IOArrow b c -> IOArrow b c
nameIOA name ar = proc b -> do
	_ <- (arr $ putStrLn . (name++) . show) -< b
	c <- ar -< b
	returnA -< c

namedOr = fun2IOA "OR" orGate
namedAnd = fun2IOA "AND" andGate
namedInverter = fun2IOA "NOT" inverter

namedHalfAdder :: --省略

main :: IO ()
main = runKleisli namedAnd (True,True) >>= print
こう書いたら最後の結果のTrueしか出て来ないんです奥さん。 Kleisli arrowの定義に>>が入って無いからでしょうか。 IO monadは>>が、「前の結果いかんにかかわらず、前のものを実行してから後のものを実行する」という動作をしてくれたので、この中に副作用を押し込めたと理解しています。 とすると、それが定義に入っていないKleisli (IO a b)は、アクションのところでモナド結合を明示的に書かないとだめそうですね。

追記:7/18

上記のコードは、arrをKleisliに書き換えれば解答編と同じように出来ます。当時はarrの型を勘違いしていました。

スポンサーサイト
コメント
この記事へのコメント
コメントを投稿する
URL:
Comment:
Pass:
秘密: 管理者にだけ表示を許可する
 
トラックバック
この記事のトラックバックURL
http://gusmachine.blog49.fc2.com/tb.php/20-c6098b36
この記事にトラックバックする(FC2ブログユーザー)
この記事へのトラックバック
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。