🔙 Back to Top

Sat Sep 7 09:39:35 JST 2013

J言語で遊ぶ

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)