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)