Sat Sep 7 09:39:35 JST 2013

J言語はHaskellのControl.Arrowを地で這わせることを
強制させる.J言語はHaskellなんかで言うところの
ポイントフリーを強要する.
それは楽しい.

問題

「整数からなるリストが与えられる.奇数がN個,偶数がM個 含まれるとするとき, N > M を判定せよ」

考えなしにHaskellで書くと

\ls -> length(filter odd ls) > length(filter even ls)

引数lsが二箇所に出てくるのがどうしようもなくて
ポイントフリーにできそうにない
lengthって二回出てくるのもいやだ

Jではこう書ける まだ全然洗練されてないけれど

([: +/ 2|]) > [: +/ 1-2|]

実際,

2 | ](filter) odd

+/length (filter)

に相当すると言えて,
右の方にも

[: +/ 1-2|] これで length.filter even に相当させてる

というわけで, あたかも

length . filter odd > length . filter even

と書いていて,J言語特有のフォークという機能によって
ポイントフリーで書き表せる

フォークなんてのは他の言語には聞いたことないと
思ったけれど,Control.Arrowは似てる

length . filter odd &&& length . filter even >>> \(x,y) -> x>y

或いは

filter odd &&& filter even >>> length *** length >>> \(x,y) -> x>y

なんか,

let both f = f *** f

みたいなのがあれば,length って二回もタイプしなくて済むんだけど
すぐには見つからなかった

あと,\(x,y)-> ってのはたしかにダサい
Jなら first > second って書けるのに!

let fork f g h = \x -> (f x) `g` (h x)