自然数の無限リストはInt?それともInteger?(別解説)

と、id:kazu-yamamotoさんの記事に書いていたようだったのでhaskell使用歴10日程度の僕は興味を持って調べてみることにしました。というのが背景です。ポリシーとしては基本仕様から調べるということで。
自然数の無限リストはInt?それともInteger?


とりあえず、[1..]ってのがhaskellではどう定義されているかを見てみませう。
http://haskell.org/onlinereport/exps.html#arithmetic-sequences ←こんな感じ。
[0..]や、[0..10]に代表されるリスト内包表記(list comprehensions)はhaskellの糖衣構文なのですね。つまり、[1..]と書くとそれは(enumFrom 1)といった式に内部で変換されてから、処理が行なわれるのです。ならばenumFromの型を見れば[1..]の型が判明するのです!! をぉ。簡単! ということで、Hugsでお試し。

Hugs> :t enumFrom
enumFrom :: Enum a => a -> [a]

えーと。なんですか? 型クラス(Enum a)において、aを受けとってaのリストを返す関数ですか。つまりenumFromは型クラス(Enum a)をサポートしていれば使えると。んじゃ、Enum aを継承しているDoubleとかでもできるの?!
…試してみた (トリビアの泉風に)。

#Hugs ver. Sep 2006
Type :? for help
Hugs> [0.22..2.33]
[0.22,1.22,2.22]
Hugs> [0.22..2.22]
[0.22,1.22,2.22]
# GHCi 6.8.2
Prelude> [0.22..2.22]
[0.22,1.22,2.2199999999999998]
Prelude> [0.22..2.23]
[0.22,1.22,2.2199999999999998]

をぉ。できるやん。GHCiは返り値がなんとなく微妙だけれど。まぁ、型的に納得できる。納得できるけれどさぁ…俺の求めている答はどこにあるのさぁ!!
(ここで少しの苦悩と逡巡があった)
…で結局はそうなると「"10"とhaskellって書いたとき、それは何の型を持つの?」という問題になる訳ですね。10って数字はIntかもしれないし、Integerかもしれないし、Doubleかもしれないのです。言語の評価機としては与えられた数値に対して、なにかしらの型を与えて処理をしないといけない訳です。特に型推論とか持っているhaskellならばなおさら。で、その規約もhaskellの言語仕様にはありました! さすが言語仕様書。
「貴様らの歩んでいる道は、我々がすでに通った道 だ!(from グラップラーバキ)」 と言われんばかりですね。
http://haskell.org/onlinereport/decls.html#default-decls ←ここ
ということで、ここを見るとモジュール内でdefault(型1, 型2)と宣言した順番にマッチさせようとすることになっています。何も指定しない場合(つまりdefaultのdefault)は"default (Integer, Double)"になっているとのこと。よって、

  • [1..]と打つとenumFrom 1として計算される。型はEnum a => a -> [a]
  • 特にdefault()で指定しない場合haskellは"1"をIntegerの"1"として認識する
  • つまりenumFrom 1の型は Integer -> [Integer] になる

結果、無限リストになる訳ですね。

んじゃ、こんなファイルを作って、Hugsでテストしてみましょう。

module Test 
    where
default (Int, Double)
k = let a=[2..] in a
Hugs> :load hogefuga.hs
Test> :t k
k :: [Int]

をぉ。Intになったね。という話ですた(オチなし)。