Haskellでフィボナッチメモ化再帰

さっき挙げたプログラムだとfib(40)ぐらいでもう数十秒ぐらいかかり、だいぶ遅いです。
メモ化再帰を使って高速化すればよいと思いましたが、Haskellの性格上、なかなか実装は困難を極めました。メモ化再帰フィボナッチをメモしておきます

fib x = if(x < 3)
        then 1
        else (fiblist !! (x-1) + fiblist !! (x-2))
fiblist = [fib x  | x <- [0,1..]]

実行結果

ghci> fib 5000
3878968454388325633701916308325905312082127714646245106160597214895550139044037097010822916462210669479293452858882973813483102008954982940361430156911478938364216563944106910214505634133706558656238254656700712525929903854933813928836378347518908762970712033337052923107693008518093849801803847813996748881765554653788291644268912980384613778969021502293082475666346224923071883324803280375039130352903304505842701147635242270210934637699104006714174883298422891491273104054328753298044273676822977244987749874555691907703880637046832794811358973739993110106219308149018570815397854379195305617510761053075688783766033667355445258844886241619210553457493675897849027988234351023599844663934853256411952221859563060475364645470760330902420806382584929156452876291575759142343809142302917491088984155209854432486594079793571316841692868039545309545388698114665082066862897420639323438488465240988742395873801976993820317174208932265468879364002630797780058759129671389634214252579116872755600360311370547754724604639987588046985178408674382863125

5000項目でも一瞬で計算できます。多倍長標準実装スゴイ。
fiblistは無限に並ぶフィボナッチ数列を表しています。fib関数ではfiblistのx-1,x-2項目を取り出して和を取るように言っていますが、これをまだ計算していなかったならばfibを再帰して...ということを繰り返し、fiblistを埋めていきます。メモ化再帰も結構きれいにかけて満足です。これを応用すればいろんなメモ化がかけそうですね。

追記

fib 0 = 0
fib 1 = 1
fib x = fiblist !! (x-1) + fiblist !! (x-2)
fiblist = [fib x  | x <- [0,1..]]

こっちのほうがエレガントですね