Programming Windows in Haskell、次の一歩がなかなかでない。
以前に簡単な説明とともにWin32でウィンドウを表示するアプリのソースを載せたわけなんですが、実はそのソースのことで書きたいことがあったのです。
ちゃんとウィンドウを表示してメッセージを描画するところまではちゃんとできて、さらに、細かいところを見ていっても、メッセージポンプはちゃんとIO型で、再帰呼び出しのループになっているし、ウィンドウプロシジャもHaskellで普通に定義して呼び出せるし、よくできてるじゃんと思ったのです。
なんですが、次のステップで僕が引っかかったのはそのウィンドウ固有のステートをどこに保持したら良いかということです…
普通にC/C++で書くのでも実はここのころはやや複雑で、まぁ、基本路線としてはSetWindowLongとかでオブジェクトをウィンドウ構造体に持たせてしまうという技を使ったりするわけなんですが、Haskellのデータ型でおんなじことをやるというのはなんだかとてもHaskellのポリシーに反する気がしたわけです。
せっかくメッセージポンプがIOモナドの再帰呼び出しループになっているんだから、そこをうまくStateT IOなモナドの再帰呼び出しループにして、WindowProcにまでStateが渡らないかなどと妄想を抱いたりもしたのですが、それをやるためにはWin32のライブラリを書き換える必要が出てきそうです。まぁ、やれればステート情報はImmutableなデータ型で表現することもできてとてもかっこいいわけです。ただし、これではメッセージポンプ一つに一つのステートという対応になってしまうので、それが情けないわけなんですが…まぁ、メッセージポンプのステートが (HWND, WndState) みたいなマップになっていれば、ウィンドウごとのステートの保持もできはしますね…
などと色々かいてみても、結局Haskell側だけじゃあ解決しない問題なので、なかなかそっちの方向へ進めてみようという気がしません。そして、メッセージポンプを利用してステートもポンプすることをあきらめるとなると必然的にステート情報をMutableなデータで表現する必要が出てくるわけです…しかし、これは何か大切なものをあきらめるような気がしてしまう…
それで、結局やったのが、ステート情報をshowで文字列に変換して、SetWindowTextでウィンドウのタイトルバーに突っ込んで、WindowProcに戻ってくるたびにGetWindowTextでとってきてreadする…まぁ、あくまでもほかの部分を前進させるためということで、ここのところ、ちゃんと決着を見たいとは思っているのですが…
誰か良い考え、持っていませんかねぇ…wxHaskellとか、もっとちゃんとしたGUIライブラリを使えというお話はごもっともなのですが…
ではでは。