ポイントフリースタイル

というものがあるらしい。なんか推奨されてるっぽいのだが...。


どちらかというと難読化してるような気がしてならない...。


とりあえずポイントフリースタイルってのは仮引数を追い出して、結合演算子(.)を多用しまくるスタイルらしい。
基本これ↓を使って変形するらしい

fg x = f(g x)
fg x = (f . g) x
fg = f . g

まぁ、数学にもあるしね。


で、試しにやってみた。

primes (x:xs) = x : (primes (filter (\y -> (mod y x) /= 0) xs))

これ。
前に書いたかもしれんけど素数を求めるやつ。
使い方は

primes [2..]

としてやらんといけんというなんかアレゲだけど気にしない。
で、仮引数はxとxsがあるのだが...。(っていうかこれできるんか)
まぁやってみる。

primes (x:xs) = x : (primes (filter (\y -> (mod y x) /= 0) xs))
--とりあえず簡単そうな先頭のxをはじき出す。
--(:)で中置から前置に変える。
primes (x:xs) = (:) x (primes (filter (\y -> (mod y x) /= 0) xs))
--flipを使って引数の順番を変える
primes (x:xs) = (flip (:)) (primes (filter (\y -> (mod y x) /= 0) xs)) x
--とりあえずxは出た。次はxsで。
--filterを第一引数ごと括弧でくくって、見た目の引数の数を減らす(セクションとかいうらしい)
primes (x:xs) = (flip (:)) (primes ((filter (\y -> (mod y x) /= 0)) xs)) x
--primesとfilter...を合成
primes (x:xs) = (flip (:)) ((primes . (filter (\y -> (mod y x) /= 0))) xs) x
--同様にflip...とprimes...を合成
primes (x:xs) = ((flip (:)) . (primes . (filter (\y -> (mod y x) /= 0)))) xs x
--xsのはじき出し完了。あ、xがまだあった...。
--とりあえずλ抽象を消すためにλのなかでyをはじき出す。
primes (x:xs) = ((flip (:)) . (primes . (filter (\y -> (0 /=) ((flip mod x) y))))) xs x
primes (x:xs) = ((flip (:)) . (primes . (filter (\y -> ((0 /=) . (flip mod x)) y)))) xs x
--yのはじき出しが完了したのでλ抽象を消す。
primes (x:xs) = ((flip (:)) . (primes . (filter ((0 /=) . (flip mod x))))) xs x
--括弧が多いが気にしない
--xのはじき出しもう一度。
--ってどうやるんだこれ。
--考え中...
--セッション化すればわかりやすい
--というか分かれば一発。
primes (x:xs) = ((flip (:)) . (primes . (filter (((0 /=) .) (flip mod x))))) xs x
primes (x:xs) = ((flip (:)) . (primes . (filter ((((0 /=) .) . flip mod) x)))) xs x
--同様に
primes (x:xs) = ((flip (:)) . (primes . ((filter . (((0 /=) .) . flip mod)) x))) xs x
primes (x:xs) = ((flip (:)) . (((primes .) . (filter . (((0 /=) .) . flip mod))) x)) xs x
primes (x:xs) = ((((flip (:)) .) . ((primes .) . (filter . (((0 /=) .) . flip mod)))) x) xs x
--不要な括弧を外す(最初から$とか使ってやればいいのだろうけど慣れてないので...
primes (x:xs) = (((flip (:)) .) . (primes .) . filter . ((0 /=) .) . flip mod) x xs x
primes (x:xs) = ((flip (:) .) . (primes .) . filter . ((/=) 0 .) . flip mod) x xs x
--で、なんか仮引数とはじき出したのが大いに食い違ってるのですが...(汗
--こうすればいいのか...?
primes xs = ((flip (:) .) . (primes .) . filter . ((/=) 0 .) . flip mod) (head xs) xs (head xs)
--よーしxsをはじき出すぞ(ヤケ
--の前に
f :: Integer -> [Integer] -> Integer -> [Integer]
f = ((flip (:) .) . (primes .) . filter . ((/=) 0 .) . flip mod)
--流石にうざいのでまとめておく。
--しかしa->[a]->aってのもアレだなぁ...。
--せめて[a]->a->aのほうがよかったかも...。
primes xs =  f (head xs) xs (head xs)
--あと引数の数増やすためにこんなのを作ってみる。
dup :: a -> (a, a)
dup x = (x, x)
--何か間違ってる気がする。
--というか間違ってる。キニシタラマケ。
primes xs = ((f (head xs) xs) . head) xs
primes xs = ((.) (f (head xs) xs) head) xs
primes xs = ((flip (.) head) (f (head xs) xs)) xs
primes xs = (((flip (.) head) . (f (head xs))) xs) xs
primes xs = uncurry ((flip (.) head) . (f (head xs))) (xs, xs)
primes xs = uncurry ((flip (.) head) . (f (head xs))) (dup xs)
primes xs = ((uncurry ((flip (.) head) . (f (head xs)))) . dup) xs
primes xs = ((.) (uncurry ((flip (.) head) . (f (head xs)))) dup) xs
primes xs = ((flip (.) dup) (uncurry ((flip (.) head) . (f (head xs))))) xs
primes xs = ((flip (.) dup) (uncurry ((flip (.) head) . ((f . head) xs)))) xs
primes xs = ((flip (.) dup) (uncurry ((((flip (.) head) .) . (f . head)) xs))) xs
primes xs = ((flip (.) dup) ((uncurry . (((flip (.) head) .) . (f . head))) xs)) xs
primes xs = (((flip (.) dup) . (uncurry . (((flip (.) head) .) . (f . head)))) xs) xs
primes xs = uncurry ((flip (.) dup) . (uncurry . (((flip (.) head) .) . (f . head)))) (dup xs)
primes xs = (uncurry ((flip (.) dup) . (uncurry . (((flip (.) head) .) . (f . head)))) . dup) xs
--なんだこの趣味の悪い物体は!!!!!
--とりあえず括弧を消す。
primes xs = (uncurry (flip (.) dup . uncurry . (flip (.) head .) . f . head) . dup) xs
primes = uncurry (flip (.) dup . uncurry . (flip (.) head .) . f . head) . dup
--グロテクスだ...。
--たしかに当初の予定のとおり仮引数は消えたけど...。
--ものはついで。fもそとに出す(ヤケっぱち
primes = (flip (.) dup) (uncurry (flip (.) dup . uncurry . (flip (.) head .) . f . head))
primes = (flip (.) dup) (uncurry ((flip (.) head) (flip (.) dup . uncurry . (flip (.) head .) . f)))
primes = (flip (.) dup) (uncurry ((flip (.) head) (((flip (.) dup) .) ((uncurry .) (((flip (.) head .) .) f)))))
primes = (flip (.) dup) (uncurry ((flip (.) head) (((flip (.) dup) .) (((uncurry .) . ((flip (.) head .) .)) f))))
primes = (flip (.) dup) (uncurry ((flip (.) head) ((((flip (.) dup) .) . ((uncurry .) . ((flip (.) head .) .))) f)))
primes = (flip (.) dup) (uncurry (((flip (.) head) . (((flip (.) dup) .) . ((uncurry .) . ((flip (.) head .) .)))) f))
primes = (flip (.) dup) ((uncurry . ((flip (.) head) . (((flip (.) dup) .) . ((uncurry .) . ((flip (.) head .) .))))) f)
primes = ((flip (.) dup) . (uncurry . ((flip (.) head) . (((flip (.) dup) .) . ((uncurry .) . ((flip (.) head .) .)))))) f
primes = (flip (.) dup . uncurry . flip (.) head . (flip (.) dup .) . (uncurry .) . ((flip (.) head .) .)) f
--何をやってるんだこれは...。
--とはいうものの、fまでの部分を考えれば
--(a -> [a] -> a -> b) -> [a] -> b
--というまぁ汎用的な(まじか?)なものになるわけだ。
--完成品
primes :: [Integer] -> [Integer]
primes = flip (.) dup . uncurry . flip (.) head . (flip (.) dup .) . (uncurry .) . ((flip (.) head .) .) $
         (flip (:) .) . (primes .) . filter . ((/=) 0 .) . flip mod

...何かを大いに間違えてる気がしてならない...。


うん。ネット見て回ってみたがあんまり推奨されて無いみたいだ(何?
なんでも(.)が二段ぐらいまではなれると普通に読み書きできるらしいのだが...


...flipつかわない方法みっけた。

fg x y = f x (g y)
fg x y = (f x . g) y
fg x = f x . g
fg x = (. g) (f x)
fg = (. g) . f

なるほど。(f .)な形じゃなくて(. f)な形ならもっとらくになるな。確かに。
というか、(flip (.) f) == (. f)か!!
考えてみれば当たり前だ...(д)

primes :: [Integer] -> [Integer]
primes = (. dup) . uncurry . (. head) . ((. dup) .) . (uncurry .) . (((. head) .) .) $
         (flip (:) .) . (primes .) . filter . ((/=) 0 .) . flip mod

でも謎。いまだ難読。


調子に乗ってさらに難読化(w

primes = (. dup) . uncurry . (. head) . (.) (. dup) . (.) uncurry . (.) ((.) (. head)) $
         (.) (flip (:)) . (.) primes . filter . (.) ((/=) 0) . flip mod

結論:ポイントフリースタイルはほどほどに。