HaskellでWPF

だがしかし、どうしてもgtkがなんとなくなじまない。
GUIに関してはWPFがすごく気に入っているので(WPFの最大の欠点は.Netだということだ)、WPFをどうしても使いたい、という気持ちを捨てきれなかった。
しょうがないから自分でラッパーを書いてみようか、ということで、C++/CLIでラッパーDLLを作って、FFIで呼び出してみたところ、思ったよりすんなりWindowを出すところまではいけた。
以下がHaskell側のコードの一部。
命名規約がHaskellっぽくないけど、将来的にWPF全体をラッピングしたらどういう命名規則にするのがいいかなあなどと浅はかな考えでとりあえずやってみた感じ。

threadWork :: Thread -> IO ()
threadWork thread = do
    app <- netApplication_New
    window <- netWindow_New
    netApplication_Run app window
    netApplication_Delete app
    return ()

main :: IO ()
main = do
    thread <- netThread_New
    netThread_SetApartmentState thread STA
    work <- wrapThreadWork $ threadWork
    netThread_Start thread work
    netThread_Join thread
    netThread_Delete thread
    return ()

こんな感じで動くようなところまではもってけるものの、当然のことながら.Netのクラスを全部手動でラッパー作成するのは労力的に無謀、ということでReflectionから情報吸い出して、対応するHaskellのコードやラッパーのコードを自動生成するようにしたいなあ。
ただ、問題はデリゲートを統一的に扱ういい方法が今のところまだ思いついてないということ。動的にILコードを生成するとかやればいけなくはなさそうだけど、まだ試せていない。
 追記:ラッパークラスを作ってやるだけで割と簡単にいけるっぽい。

てか、これを応用するとIronRubyじゃないrubyからもWPFするとかもできそうね。

調べてみた限りではHaskellWPFの需要はあまりなさそうに見えたんだけど、世間的にはどうなんだろう。もしいろいろうまく解決できたら、ちゃんとしたライラブリっぽくした方がいいのかしらん。

gtk2hs

その次に試してみたのが、gtk2hs。linux系のOSならgtkだし、Leksah(Haskellで書かれたHaskellIDEらしい)はgtkで書かれてそう(?)、ということもあって、少なくともこれなら最低限のことはできるはず、と考えて試してみた。

以下に描かれている通りにやってみれば、うまくインストールできた。
http://projects.haskell.org/gtk2hs/download/

ちなみに検索するとgtk2hsのインストール仕方みたいなのが書いてあるページが複数あったのだが、(おそらく私の不勉強もあって)どの方法でもうまくはいかず、公式サイトの記載通りにやればいっぱつでいけた。

で、結論としては、動作については申し分なかったので、haskellGUIやろうという人はここへいくのが無難。

hs-dotnet

次に試してみたのが、hs-dotnetWPFみたいなことがやりたいなら.Netを使ってしまえばいいじゃない、という発想。
以下の記事などを参考にしつつ試してみた。
http://d.hatena.ne.jp/sirocco/20101026/1288085914

文字列をSjisに変換する必要があったり、記事にも書かれている通り、非常にたちあがりが遅かったりと非常にうんにょりする出来。
そして、最大の問題点はどうやらこれではWPFはそのままではできないらしいということ。もしかすると、実はできるんだったりするかもしれないけどちょこちょこいじった限りではできなかった。あまり詳しくはないが、COMのインターフェースを使ってやっているせい?

GLUT

最初に試してみたのがGLUT
これは最新のHaskell Platformだと最初から入ってるので、インストールとかで失敗することはまずなさげ。
ただし、これでWindowを作ると、Windowを閉じてもprogramが終わらない問題が発生した。
この問題はdllをOpenGLUTのもので置き換えてやると直った。

が、日本語フォントを表示する手段が用意されてないらしい、というのが最大の問題点となった。

別のライブラリを使えば表示できないこともないらしいけど、Windowsでできるのかよくわからなかったのもあって断念した。

yesodでpostgresqlを使う@Windows7 64bit環境

ふと思い立ってyesodを動かしてみようと思ったのだけど、せっかくならsqliteじゃなくてPostgreSQLを使用したい。それなりに詰まったのでメモを残してみようかと。

環境とか使用したソフトのバージョンは以下のような感じ。

  • Windows7 Ultimate SP1 64bit
  • Haskell Platform 2011.4.0.0
  • PostgreSQL 9.1.3 32bit
    • Haskellが32bitなので64bitは使わない方が無難。ちゃんと確認はしていないですが、クライアント向けのライブラリさえ32bit用意してしまえばDBサーバ側は64bitでもいけそうな気はする。
    • http://www.postgresql.jp/PostgreSQL/9_1/9_1_3 からダウンロード
  • Pcre for Windows 7.0
  • yesod-platform 1.0.3.4
    • たまたまなのか、最初1.0.2や1.0.3.2でインストールできなかった。そういうときは低いバージョンに切り替えたほうがよさそう。1.0.1ならインストールできたけど、そうこうしてるうちに1.0.3.3になってインストールできるようになった。その後すぐに1.0.3.4になったので最終的にこれに。

あと、cygwin環境から実行してインストールできたけど、下手にcygwinの/usr/libとかにライブラリやらヘッダやらのパスを通していると引っかかるっぽいのでご注意。何台か試したうちの一台(WindowsXPだけど)はこれが原因でしばらくはまった。

  1. 上記のyesod-platform以外を全部インストール
  2. $ cabal update
  3. $ cabal install yesod-platform
  4. $ yesod init
    • いろいろ聞かれるので適当に入力。
    • DBの種類を聞かれたらp(postgresql)を選択する。
  5. $ cd <できたフォルダ>
  6. $ cabal install
    • pcreやpostgresqlにライブラリやヘッダのパスが通っていない場合は、エラーが出て--extra-include-dirだとか--extra-lib-dirだとか(ちゃんと覚えてないけど)を設定しろと言われるので設定してやる。
    • それでもpcreのdllだかのリンクができないとエラーが出たので、pcreのbinの中のpcre3.dllをpcre.dllって名前に変えて C:\Windows\SysWOW64 とかに放りこんでやるとリンクできるっぽい。
    • 追記:deployしようとしたときなどにはpcre3.dllを要求したりもするので、pcre.dllとpcre3.dllという2つのファイルに増やしてSysWOW64においておくのがよさそう。ちょっと気持ち悪いけど
  7. postgresql側にアカウントとかデータベースとかを作成する。
  8. <できたフォルダ>/config/postgresql.yml を編集してDB名やアカウントやパスワードを設定する。
  9. $ yesod devel
    • これでしばらく待ってエラーが出なければ、ブラウザで http://localhost:3000/ を見てそれっぽいページが表示されればOK

もしHaskell-Platformが64bitになってもいろいろ64bitにならないと動かせなさそうなので、使えるようになる日は遠そう。まあ、自分でビルドすればなんとかなるかもだけど。

オブジェクトのプロパティ

オブジェクトのプロパティについていろいろやってみた。
"get"や"set"や"Item"が言語仕様として気持ち悪いなあ。
もう少しスマートにならんものか。


というわけでまたテケトーコード

続きを読む