[Haskell] キモいフィボナッチ数列の解読を試みる


前回のフィボナッチ数列の記事に, 匿名さんからコメントをいただきまして.

> 以下のフィボナッチ数列のリスト定義はとてもキモいので、ぜひご堪能下さい。
> fib = 0:1:zipWith (+) fib (tail fib)

( http://chomado.ciao.jp/programming/haskell-フィボナッチ数列/#comment-487 )

おおおおお一行や!!! これはキモそうだ!!(大興奮)

zipWith関数 … 二引数関数を使って二つのリストを混ぜ合わせる関数

zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]

(* [ c ](スペース無し) って書くと, 入れてるプラグインの影響で, C言語だと認識されてしまうので, あえて上では[c(全角)]と書いています )

そんで,
zipWith (+) fib (tail fib)
ここは何をしているかというと…
うーん…
難しい…

最初 fib の中身は
[0, 1, …](2番目までしか分かってないリスト)
だけで, そこに zipWith (+) fib (tail fib) をくっつけるわけだけど,

この状態での tail fib は [1] だから,

zipWith (+) fib [1]

で,

えーーーーーっと,

ああああ混乱してきた!!!!!! わかんない!!! 難しい!!! あとで考える!!!><

ーーー 追記 ーーーー
Twitterで助言をいただきました(T_T)ありがとうございます

(あと, 理解した後で見てみたら, 何もキモくなくて, 自然なコードだと思った)

fib = 0:1:zipWith (+) fib (tail fib)

zipWith (+) fib (tail fib)

これは,

zipWith (+) (0:1…) (1:1…)
=
[(+) 0 1, (+) 1 1, …]

無限ループにならないの?

遅延評価だから大丈夫なんだって!
take 10 fib
とかで値を取り出せる!

余談

秀逸なホモ投下


コメントを残す

メールアドレスが公開されることはありません。