Hatena::ブログ(Diary)

あどけない話

2013-02-01

tailをなくしたフィボナッチ数列

以下の内容は比較的どうでもいいことなので、暇な人だけ読んで下さい。

Haskell では、head と tail という関数は使うなと言われる。なぜなら、引数が空リストのときにエラーを返すからである。純粋な関数は全域関数であるべきだが、head と tail は div などと共に、この規律から逸脱している。

コーディング規約として、head や tail を禁止している組織もあるようだ。僕は、絶対に空リストでないことが保証されるところなら、まぁ、head や tail は使ってもいいかなと思う。

head や tail が、ある意味 Haskell の恥であるにも関わらず、以下のフィボナッチ数列のコードは、盛んに引用される。

fibs :: [Integer]
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

tail 不要論派の Haskeller なら、このコードは許せないだろう。しかし、tail を取り除けない人がほとんどではないか?

関数引数として書く変数名には、@パターンが使えることは、Haskeller のほとんどが知っているだろう。実は、トップレベルの変数名にも@パターンが利用できる。だから、tail を取り除いて、以下のようなコードが書ける。

fibs,fibs' :: [Integer]
fibs@(_:fibs') = 0 : 1 : zipWith (+) fibs fibs'

分かりやすくなったのか、分かりにくくなったのか、微妙な感じではあるけれど。

追記

「二番目のコードは、パターンマッチがあるので許せない!」という方には、中野さんが書いたこのコードをどうぞ。

fibs,fibs' :: [Integer]
fibs  = 0 : fibs'
fibs' = 1 : zipWith (+) fibs fibs'

あわせて読みたい

nobsunnobsun 2013/02/01 22:28 関数引数のパターンマッチが網羅的でないというなら,許せないというのは判る気がするけど...二番目のコードが許せないというこころがいまいち腑におちないです.どういう気持ちなんでしょうか?

kazu-yamamotokazu-yamamoto 2013/02/01 22:59 [] が来たらどうするんだ、という気持ちだと思われます。来ませんけど。

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


画像認証

トラックバック - http://d.hatena.ne.jp/kazu-yamamoto/20130201/1359703111