Haskell の函数を pointfree にするコマンド pointfree
もう closed になっているが,Stackoverflow に投稿された sof 氏による質問:
Haskell で,楽で正確に,函数を point free な形にできるやり方を探している. Readable な結果を得られるものがいい.どうするのがいいだろうか?
Jamshidh による回答:
“pointfree” っていうプログラムがある.
cabal install pointfree
でインストールして,
$ pointfree "\x -> x+1" (1 +)
警告:すごくいい感じに pointfree になることもあるけど,かなり scary な結果になることもある…
なるほど.
いろいろ試してみよう
$ pointfree "\x y -> x y"
id
$ pointfree "\x y -> f (g x y)"
(f .) . g
$ pointfree "\f (x,y) -> f x y"
(`ap` snd) . (. fst)
$ pointfree "\(a,b) -> (b,a)"
uncurry (flip (,))
$ pointfree "\x -> x*x"
join (*)
$ pointfree "\f l -> zipWith (,) (map (f . fst) l) (map snd l)"
(`ap` map snd) . (zip .) . map . (. fst)
$ pointfree "\x y -> (f x == f y)"
(. f) . (==) . f
ほー(後半ひどい).let ..in
とかも使えるようになっているようだ.
ap
は Control.Monad にあるようだ.
Pointfree についてはいくつか参考になる記事があります:
- ポイントフリースタイルの歪んだ美 - capriccioso String Creating(Object something){ return My.Expression(something); }
- ポイントフリースタイル入門 - melpon日記 - HaskellもC++もまともに扱えないへたれのページ
- ポイントフリーコンバータ - MEMO:はてな支店
- ポイントフリー - 西尾泰和のはてなダイアリー
見比べてみるのも良さそう.
ちなみにもうひとつの,maxgabriel氏による回答では HaskellWiki での記述が紹介されています.Lambdabot もこの機能を持っているらしい.