purescriptからjqueryを使う

purescriptはFFIjavascriptが呼び出せるようで、jqueyのバインディングのライブラリがあったので試してみた。

動かすサンプルは本家のexampleから取ってきたので、実質ビルドの定義とか書いただけですが、いざ使おうと思うとその辺が一番めんどくさいので、一式ソースは以下に置いておきました。
https://github.com/minamijoyo/purescript-jquery-example

ポイントだけ補足。
bower.jsonでpurescript-jqueryをdependenciesに追加。purescript-foreignはpurescript-jqueryから間接的に依存してるので明示的に書かなくてもよいかもしれない。

  "dependencies": {
    "purescript-foreign": "~0.2.0",
    "purescript-jquery": "0.2.3"
  }

Grunt.jsでsrc/Main.pursをコンパイルしたものをpublic/js/Main.jsとかに配置するようにする。

		srcFiles: ["src/**/*.purs", "bower_components/**/src/**/*.purs"],
		psc: {
			options: {
				main: "Main",
				modules: ["Main"]
			},
			all: {
				src: ["<%=srcFiles%>"],
				dest: "public/js/Main.js"
			}
		},

public/index.htmlでjqueryの本体とMain.jsを読み込む。

<!DOCTYPE html>
<html>
<head>
<title>Example for purescript-jquery</title>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="js/Main.js"></script>
</body>
</html>

読み込むjqueryのバージョンはpurescript-jquery 0.2.3ではjquery1.10.2を使ってるよう。
https://github.com/purescript-contrib/purescript-jquery/blob/master/html/jquery.js

最後にMain.purs書く。今回は本家のサンプルそのままです。

module Main where

import Data.Either
import Prelude
import Data.Foreign
import Data.Foreign.Class
import Control.Monad.Eff
import qualified Control.Monad.JQuery as J
import Debug.Trace

main = J.ready $ do
  -- Get the document body
  b <- J.body

  -- Create a text box
  div <- J.create "<div>"
  input <- J.create "<input>"
  "Your Name: " `J.appendText` div
  input `J.append` div
  div `J.append` b

  -- Create a paragraph to display a greeting
  greeting <- J.create "<p>"
  { color: "red" } `J.css` greeting
  greeting `J.append` b

  -- Listen for change events on the text box
  flip (J.on "change") input $ \_ _ -> do
    Right name <- read <$> J.getValue input
    trace $ "Name changed to " ++ name
    J.setText ("Hello, " ++ name) greeting

なんとなく何やってるかは雰囲気で伝わるかと思うけど、inputボックス作って文字列name入力すると"Hello, " + nameと返してくれるかんじ。

ビルドは

$ npm install
$ bower update
$ grunt

してからpublic/index.htmlをブラウザで開けばよい。

使ってみた雑感。正直煩雑な感じで読みづらい、これぐらいのことなら普通のjsの方が読みやすいし分かりやすい感はんぱない。purescriptはUIのDOM触るような使いどころじゃなくて、もうちょっとjsでもモデルのロジック周りに限定して使うような使い方にしかならんのかなぁとか思いました。