Hatena::ブログ(Diary)

あどけない話

2010-07-02

関数合成の妙技

Haskell 初心者は括弧ばかりの Lisp のようなコードを書く。中級者になると、($) が多くなる。上級者(言い過ぎか?)になると、($) が消えて、(.) が多くなる。この記事では、上級者になるコツをちょっと教えちゃおう。

括弧だらけのコード

では、以下の例について考えよう。

foo p xs = sum (filter p (map (+1) xs))

括弧が多くて、いかにも初心者が書いたコードだ。foo は、以下のように動く。

foo even [1..6]
→ 12

($) を使う

では、括弧を ($) に置き換えてみよう。そうするには、一番右側にある閉じ括弧を消して、対応する開き括弧を ($) に置き換えればよい。だからこうなる。

foo p xs = sum $ filter p $ map (+1) xs

だいぶ見やすくなった。

(.) を使う

map (+1) xs は、(map (+1)) xs という意味で、map (+1) (xs) とも解釈できるから、括弧を($)に置き換える手法を適用して、以下のように変形できる。

foo p xs = sum $ filter p $ map (+1) $ xs

こうなると、右辺の最後の変数以外は、一引数関数の連なりになるから、($) を (.) で置き換えられる。

foo p xs = sum . filter p . map (+1) $ xs

そして、右辺と左辺の最も右側に xs があるので、これを削ることができて、最終的にはこうなる。

foo p = sum . filter p . map (+1)

これで、Haskell らしいコードのできあがり。

rahaemarahaema 2010/07/05 12:21 いつも楽しみに見てます。さて,最後辺りですが,「そして,右辺と左辺の最も左側に…」とありますが,右側ですよね。

kazu-yamamotokazu-yamamoto 2010/07/06 16:14 間違いのご指摘、ありがとうございます。直しました。

tmiyatmiya 2010/07/06 16:25 更にpも削ってpoint-freeに、という話はしないのでしょうか?

kazu-yamamotokazu-yamamoto 2010/07/08 00:49 point-free にすると、理解しにくくなりませんかね?

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証