Xeebi

home categories feeds

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 とかも使えるようになっているようだ. apControl.Monad にあるようだ.

Pointfree についてはいくつか参考になる記事があります:

見比べてみるのも良さそう.

ちなみにもうひとつの,maxgabriel氏による回答では HaskellWiki での記述が紹介されています.Lambdabot もこの機能を持っているらしい.