この記事はScalaz Advent Calendarの13日目の記事です。
Codensityについてググると、
The Mother of all Monads
という記事が見つかる。
Codensityは継続モナドとほぼ同じものみたい。
この記事にある例をScalaで書いてみる。
Option
Disjunction
なるほど。
CodensityがOptionやDisjunctionとして動く。
でもこれってIdTじゃ(ry
Codensityは継続モナドのようなもの、ということで継続らしい例を書いてみる。
iprintで、計算の経過を表示する。
Some(bar)とNoneが表示される。
継続を破棄するbreakを定義し、for式で使ってみる。
Some(bar)だけが表示される。
無事、計算が破棄された。
Codensityはあるモナドにおいて計算量を減らせることがわかった。
他にも何か出来そうだが、わたしが思いついたのはこれくらい。
2012年12月13日木曜日
2012年12月9日日曜日
Injectiveを考える
この記事はScalaz Advent Calendarの9日目の記事です。
この記事に書いてあることは役にたたないと思うので、あまり気合を入れて読まないでください。
Scalazには、Injectively, Injective1 ~ Injective5が定義されている。
よくわからない。
Injectiveをググってみると、どうやら単射のことっぽい。
Injectiveは型パラメータをとる型を型引数にとる。
つまり、種(カインド)が* -> *や、* -> * -> *である型が単射であるいう制約をつけるものではないかと考えた。
とりあえずInjectiveの例を列挙してみる。
List
ふつうに定義できる。
type member
Hoge#Fは未定義なので、インスタンスの供給は出来ない。
dependent method types
明示的にインスタンスを渡す必要はあるが、コンパイルすることは可能。
ふむ、よくわからない。
単射にならない型がもしあるのだとしたら、F[_]に対して、ある型Aを渡した時にコンパイルが通らないということだろうか。
ということは、F[_]がとりうる型に対して制約をかければよいということだろう。
次のような例を書いた。
なるほど。
確かに、単射ではないからInjectiveのインスタンスが定義出来ない。
Injectiveの意味がようやく理解できた。
InjectiveはLiskovのコードで使われているが、まあ、よくわからない。
わからなくても、この先困るということもないと思う。
この記事に書いてあることは役にたたないと思うので、あまり気合を入れて読まないでください。
Injective
Scalazには、Injectively, Injective1 ~ Injective5が定義されている。
よくわからない。
Injectiveをググってみると、どうやら単射のことっぽい。
Injectiveは型パラメータをとる型を型引数にとる。
つまり、種(カインド)が* -> *や、* -> * -> *である型が単射であるいう制約をつけるものではないかと考えた。
とりあえずInjectiveの例を列挙してみる。
List
ふつうに定義できる。
type member
Hoge#Fは未定義なので、インスタンスの供給は出来ない。
dependent method types
明示的にインスタンスを渡す必要はあるが、コンパイルすることは可能。
ふむ、よくわからない。
単射にならない型がもしあるのだとしたら、F[_]に対して、ある型Aを渡した時にコンパイルが通らないということだろうか。
ということは、F[_]がとりうる型に対して制約をかければよいということだろう。
次のような例を書いた。
なるほど。
確かに、単射ではないからInjectiveのインスタンスが定義出来ない。
Injectiveの意味がようやく理解できた。
InjectiveはLiskovのコードで使われているが、まあ、よくわからない。
わからなくても、この先困るということもないと思う。
2012年12月5日水曜日
ClojureでJavaFX & Web Start
JavaFX Advent Calendar 2012
5日目の記事です。
三目並べ
Cojureで三目並べの続き。
ここでは三目並べのJavaFX実装について書きます。
ゲームのロジックは作ってあるのであとは描画のところを実装するだけ。
JavaFXの基本として、メインクラスにjavafx.application.Applicationを継承します。
ここではgen-classを使って、Javaのclassファイルにコンパイルします。
mainメソッドではApplication.launchを呼び出します。
あとはstartメソッドでtic-tac-toe.game.Canvasを実装し、各パネルにhandlerを登録します。
ClojureでGUIライブラリを使うときに便利なのがdoto。
あるインスタンスのもとで、メソッドを連続して実行することが出来ます。
Rubyのinstance_evalのようなものですね。
EventHandlerなどのインターフェースはreifyを使うことで実体を得られます。
JavaFX Script時代にはいくつかWeb Startのアプリケーションを作ったことが
ありましたが、JavaFX 2になってからは初のWeb Startです。
まずは、lein2 uberjarでstandaloneなjarを作ります。
20MBもあるのはClojure+JavaFXのclassファイルが入ってる所為です。
次にjnlpですが、こんな感じになりました。
all-permissionsになっているのはClojureを実行するためです。
多分JRubyやGroovyでもall-permissionsが必要になるはず。
all-permissionsを要求するので、署名をしなければなりません。
keytoolで適当なkeystoreを作ります。
keytool -genkey -keystore foo -alias bar
fooというファイルが作られるので、jarsignerを使ってjarに署名します。
jarsigner -keystore foo target/tic-tac-toe-0.1.0-SNAPSHOT-standalone.jar bar
これでWeb Startで起動できます。
実際に試す場合はjnlpファイルのcodebaseを
codebase="file:/home/halcat0x15a/tic-tac-toe/"
のように書き替え、
javaws tic_tac_toe.jnlp
で実行可能です。
このプログラムではたいしたことをしていませんが、JavaFXのおかげで、Swingよりもシンプルで簡単にGUIを書けるようになったと思います。
他のGUIライブラリと比べても、ライブラリの設計は格段に良くなったと感じます。
Web Startは、ScalaやClojureなどのランタイムが他に必要な言語にはあまりむかないのかなと感じました。
プログラム+ライブラリ+ランタイムとなると、かなりファイルサイズが大きくなってしまいます。
5日目の記事です。
三目並べ
Cojureで三目並べの続き。
ここでは三目並べのJavaFX実装について書きます。
ゲームのロジックは作ってあるのであとは描画のところを実装するだけ。
Application
JavaFXの基本として、メインクラスにjavafx.application.Applicationを継承します。
ここではgen-classを使って、Javaのclassファイルにコンパイルします。
mainメソッドではApplication.launchを呼び出します。
あとはstartメソッドでtic-tac-toe.game.Canvasを実装し、各パネルにhandlerを登録します。
ClojureでGUIライブラリを使うときに便利なのがdoto。
あるインスタンスのもとで、メソッドを連続して実行することが出来ます。
Rubyのinstance_evalのようなものですね。
EventHandlerなどのインターフェースはreifyを使うことで実体を得られます。
Web Start
JavaFX Script時代にはいくつかWeb Startのアプリケーションを作ったことが
ありましたが、JavaFX 2になってからは初のWeb Startです。
まずは、lein2 uberjarでstandaloneなjarを作ります。
20MBもあるのはClojure+JavaFXのclassファイルが入ってる所為です。
次にjnlpですが、こんな感じになりました。
all-permissionsになっているのはClojureを実行するためです。
多分JRubyやGroovyでもall-permissionsが必要になるはず。
all-permissionsを要求するので、署名をしなければなりません。
keytoolで適当なkeystoreを作ります。
keytool -genkey -keystore foo -alias bar
fooというファイルが作られるので、jarsignerを使ってjarに署名します。
jarsigner -keystore foo target/tic-tac-toe-0.1.0-SNAPSHOT-standalone.jar bar
これでWeb Startで起動できます。
実際に試す場合はjnlpファイルのcodebaseを
codebase="file:/home/halcat0x15a/tic-tac-toe/"
のように書き替え、
javaws tic_tac_toe.jnlp
で実行可能です。
雑感
このプログラムではたいしたことをしていませんが、JavaFXのおかげで、Swingよりもシンプルで簡単にGUIを書けるようになったと思います。
他のGUIライブラリと比べても、ライブラリの設計は格段に良くなったと感じます。
Web Startは、ScalaやClojureなどのランタイムが他に必要な言語にはあまりむかないのかなと感じました。
プログラム+ライブラリ+ランタイムとなると、かなりファイルサイズが大きくなってしまいます。
ClojureScriptでgoog.graphics
altjs Advent Calendar 2012
5日目の記事です。
三目並べ
Cojureで三目並べの続き。
ここでは三目並べのClojureScriptによる実装について書きます。
ゲームのロジックは作ってあるのであとは描画のところを実装するだけ。
描画にはgoog.graphicsを使うことにします。
ClojureScriptはGoogle Closure Libraryで実装されており、nsでJavaScriptのライブラリをrequireすることが出来ます。
各種定数。
tic-tac-toe.game.Canvasを実装します。
main関数を定義します。
HTMLはコンパイルされたJavaScriptを読み込み、main関数を呼び出します。
これで動いてほしいところですが、cljs.core.logicがバグってるので、コンパイルされた.jsの修正が必要です。
cljs.core.logic.macros._take_STAR_のところをcljs.core.logic._take_STAR_に変更します。
masterでは直ってますが、修正版がpublishされていないのが悲しいですね。
いままでもClojureScriptについていろいろ書いてますが、やはりClojureは書いてて楽しいです。
最近はprotocolとrecordとmacroが好みです。
論理プログラミングで書いたコードがWeb上で動いているのはなかなかおもしろいと思うのですが、コンパイルされたJavaScriptのコードをみるとものすごくカオスです。
Google Closure Compilerによるアシストがあるとはいえ、ファイルサイズは比較的大きくなるので、注意です。
cljsbuildのおかげで、今回のようなJVMとWebの両方で動くようなコードが書けるので、これからClojureScriptを使う人には是非知ってもらいたいものです。
5日目の記事です。
三目並べ
Cojureで三目並べの続き。
ここでは三目並べのClojureScriptによる実装について書きます。
ゲームのロジックは作ってあるのであとは描画のところを実装するだけ。
goog.graphics
描画にはgoog.graphicsを使うことにします。
ClojureScriptはGoogle Closure Libraryで実装されており、nsでJavaScriptのライブラリをrequireすることが出来ます。
各種定数。
tic-tac-toe.game.Canvasを実装します。
main関数を定義します。
HTMLはコンパイルされたJavaScriptを読み込み、main関数を呼び出します。
これで動いてほしいところですが、cljs.core.logicがバグってるので、コンパイルされた.jsの修正が必要です。
cljs.core.logic.macros._take_STAR_のところをcljs.core.logic._take_STAR_に変更します。
masterでは直ってますが、修正版がpublishされていないのが悲しいですね。
雑感
いままでもClojureScriptについていろいろ書いてますが、やはりClojureは書いてて楽しいです。
最近はprotocolとrecordとmacroが好みです。
論理プログラミングで書いたコードがWeb上で動いているのはなかなかおもしろいと思うのですが、コンパイルされたJavaScriptのコードをみるとものすごくカオスです。
Google Closure Compilerによるアシストがあるとはいえ、ファイルサイズは比較的大きくなるので、注意です。
cljsbuildのおかげで、今回のようなJVMとWebの両方で動くようなコードが書けるので、これからClojureScriptを使う人には是非知ってもらいたいものです。
Clojureで三目並べ
Lisp Advent Calendar 2012
6日目の記事です。
三目並べ
ここでは三目並べソルバについて書きます。
三目並べ、すなわち◯×ゲームです。
小学生の頃とかやってました。
このゲームは両者が最善を尽せば必ず引分けになるゲームで、その最善手もわかりやすいので他人とやってもだいたいドローになります。
この三目並べで盤面から次の手を返すプログラムを、ClojureとClojureScriptの両方で動くように作成します。
今回は論理プログラミングでこのパズルを解きます。
最初にnamespaceですが、ClojureとClojureScriptの両方で動かす為に、多少の黒魔術があります。
;*CLJSBUILD-REMOVE*;はcljsbuildがビルド時に削除してくれるコメントです。
core.logicがclj版とcljs版で違うnamespaceを使っているのでこうなっています。
盤面で、空いているところはnilとします。
not-nil?という述語を作るために、!=を使いたいところですがcljs版に存在しないのでprojectを使います。
projectはcore.logicで使われている変数にあたるものから値を取り出します。
盤面が空いていたらコマを置く述語write。
コマが2連続で続いていたら自分であろうと相手であろうと決着します。
そのため、コマを優先して置く述語checkを定義します。
これで補助の述語の定義は終りです。
あとは愚直に盤面を検査します。
checkやwriteの順番を並べ変えると強くなったり弱くなったりします。
ここではなるべく中心にコマを置くように書いています。
盤面から次の手を返す述語が定義できました。
もう1つ、ゲームが終了したか調べる述語も定義します。
実際の使い方はこんな感じ。
敵味方の区別をつけていないので思った通りの手が返ってきていませんが、勝てないというのもつまらないのでこのままにします(手抜き)。
これらの関数を使い、ゲームのロジックを書きます。
Canvasプロトコルを実装し、play関数を各パネルをクリックした時のhandlerとして登録することで動きます。
JavaFXによる実装とgoog.graphicsによる実装を書きました。
core.logicによる論理プログラミングは慣れていないせいか、とても頭をつかいました。
完成したコードは愚直だけれど分かり易いものになりました。
こういった書き方が出来ることが論理プログラミングの1つの利点でもあると思います。
ゲームのロジックに関してはあまり綺麗に書けなかったのですが、各ライブラリと協調できるうまい書き方を知りたいものです。
6日目の記事です。
三目並べ
ここでは三目並べソルバについて書きます。
tic tac toe
三目並べ、すなわち◯×ゲームです。
小学生の頃とかやってました。
このゲームは両者が最善を尽せば必ず引分けになるゲームで、その最善手もわかりやすいので他人とやってもだいたいドローになります。
この三目並べで盤面から次の手を返すプログラムを、ClojureとClojureScriptの両方で動くように作成します。
core.logic
今回は論理プログラミングでこのパズルを解きます。
最初にnamespaceですが、ClojureとClojureScriptの両方で動かす為に、多少の黒魔術があります。
;*CLJSBUILD-REMOVE*;はcljsbuildがビルド時に削除してくれるコメントです。
core.logicがclj版とcljs版で違うnamespaceを使っているのでこうなっています。
盤面で、空いているところはnilとします。
not-nil?という述語を作るために、!=を使いたいところですがcljs版に存在しないのでprojectを使います。
projectはcore.logicで使われている変数にあたるものから値を取り出します。
盤面が空いていたらコマを置く述語write。
コマが2連続で続いていたら自分であろうと相手であろうと決着します。
そのため、コマを優先して置く述語checkを定義します。
これで補助の述語の定義は終りです。
あとは愚直に盤面を検査します。
checkやwriteの順番を並べ変えると強くなったり弱くなったりします。
ここではなるべく中心にコマを置くように書いています。
盤面から次の手を返す述語が定義できました。
もう1つ、ゲームが終了したか調べる述語も定義します。
実際の使い方はこんな感じ。
敵味方の区別をつけていないので思った通りの手が返ってきていませんが、勝てないというのもつまらないのでこのままにします(手抜き)。
これらの関数を使い、ゲームのロジックを書きます。
Canvasプロトコルを実装し、play関数を各パネルをクリックした時のhandlerとして登録することで動きます。
JavaFXによる実装とgoog.graphicsによる実装を書きました。
雑感
core.logicによる論理プログラミングは慣れていないせいか、とても頭をつかいました。
完成したコードは愚直だけれど分かり易いものになりました。
こういった書き方が出来ることが論理プログラミングの1つの利点でもあると思います。
ゲームのロジックに関してはあまり綺麗に書けなかったのですが、各ライブラリと協調できるうまい書き方を知りたいものです。
2012年12月1日土曜日
Isomorphism
Scalaz Advent Calendar!
あるcase classに対してMonoidを定義したいとき、大体のものはTupleのMonoidのインスタンスが使えると思います。
こんなときにIsomorphismMonoidが使えます。
Monoid以外の型クラスを定義したい時もこんな感じで使える。
このように、データ構造が同じもののインスタンスを流用する場合はIsomorphismが使えます。
<=>[A, B]はIso[Function1, A, B]のtype aliasで、to: A => Bとfrom: B => Aを定義します。
IsomorphismMonoidなどの型クラスは、toを使って実装されていることに注意しましょう。
Isomorphism
あるcase classに対してMonoidを定義したいとき、大体のものはTupleのMonoidのインスタンスが使えると思います。
こんなときにIsomorphismMonoidが使えます。
Monoid以外の型クラスを定義したい時もこんな感じで使える。
このように、データ構造が同じもののインスタンスを流用する場合はIsomorphismが使えます。
<=>[A, B]はIso[Function1, A, B]のtype aliasで、to: A => Bとfrom: B => Aを定義します。
IsomorphismMonoidなどの型クラスは、toを使って実装されていることに注意しましょう。
2012年10月31日水曜日
ClojureでLisp評価器
SICP読書会、毎週月曜19時からmixiでやってます。
現在第4章の超循環評価器を作っています。
4章の一番最初に出てくるevalの定義は以下の通り
とてもわかりやすいけど、データ主導にしたいよね、そうしよう、というのが問題4.3にあります。
これをClojureっぽく書くことを考えてみる。
ClojureといったらやっぱProtocolだよね!ということでプロトコルベースで考える。
とりあえず評価器プロトコル、Eval(uator)の定義
このプロトコルを実装したリテラルの評価器を書いてみる。
部分関数っぽくしたいのだけど、例外を投げるか迷った。
今回はとりあえずこれで。
このように、小さな評価器をいっぱい作って合成していくという考え方。
ifやdefineやbeginなんかのspecial formをチェックする関数tagged?の定義
先頭要素を比較するだけ。
これを使って、special formを以下のように表してみる
Specialを使ったquote
ifは式を評価しなければいけない。
しかし、どの評価器を使えばいいのかわからない。
評価器を引数にとるという選択肢もあるけど、不都合がある。
この式を評価するとよくわからないエラーが投げられると思う。
ここでは評価機が部分適用されたeval関数をとることにする。
一番大事な評価器を合成する関数
やっていることは簡単、引数の先頭の評価器から順に、式を評価器で評価して失敗したら次の評価器で評価するという評価器を作っているだけ。
これを使ってifとliteralだけが使えるlispを定義すると以下のようになる。
実行
ヤッター
こんな感じで小さな評価器を書いていって大きな評価器を作っています。
なかなか楽しい。
今回のプログラムはScalaBaseで@maeda_さんが発表されていた、Javascript as an Embedded DSLに触発されて書いてみました。
おもしろいので読んでみるとよいです。
次はぱーさーこんびねーたについて書く、書きたい、書けたらいいな。
現在第4章の超循環評価器を作っています。
4章の一番最初に出てくるevalの定義は以下の通り
とてもわかりやすいけど、データ主導にしたいよね、そうしよう、というのが問題4.3にあります。
これをClojureっぽく書くことを考えてみる。
Protocol
ClojureといったらやっぱProtocolだよね!ということでプロトコルベースで考える。
とりあえず評価器プロトコル、Eval(uator)の定義
このプロトコルを実装したリテラルの評価器を書いてみる。
部分関数っぽくしたいのだけど、例外を投げるか迷った。
今回はとりあえずこれで。
このように、小さな評価器をいっぱい作って合成していくという考え方。
special form
ifやdefineやbeginなんかのspecial formをチェックする関数tagged?の定義
先頭要素を比較するだけ。
これを使って、special formを以下のように表してみる
Specialを使ったquote
if
ifは式を評価しなければいけない。
しかし、どの評価器を使えばいいのかわからない。
評価器を引数にとるという選択肢もあるけど、不都合がある。
この式を評価するとよくわからないエラーが投げられると思う。
ここでは評価機が部分適用されたeval関数をとることにする。
compose
一番大事な評価器を合成する関数
やっていることは簡単、引数の先頭の評価器から順に、式を評価器で評価して失敗したら次の評価器で評価するという評価器を作っているだけ。
これを使ってifとliteralだけが使えるlispを定義すると以下のようになる。
実行
ヤッター
まとめ
こんな感じで小さな評価器を書いていって大きな評価器を作っています。
なかなか楽しい。
今回のプログラムはScalaBaseで@maeda_さんが発表されていた、Javascript as an Embedded DSLに触発されて書いてみました。
おもしろいので読んでみるとよいです。
次はぱーさーこんびねーたについて書く、書きたい、書けたらいいな。
登録:
投稿 (Atom)