instance Enum Int を実装したので、それを用いて Arithmetic Sequences をサポートする。
arithmeticseq.hs はランタイムでエラー、少し改変した arithmeticseq2.hs は通った。
調査するには大きいので、各々小さくする:
aseq.hs:
main =do print $ take 5 ([n..] :: [Int])
where n = 13
こちらは、ランタイムにて IntShowFunc: must not occur となり abend.
aseq2.hs:
main =do print $ take 5 [n..]
where n :: Int
n = 13
こちらは OK.
両者の Core を見比べてみる。
まず、aseq.hs の方(エラーする):
(Main.main :: (Prelude.IO ())) =
let
(Main.l0.l0.n :: ([Prelude.Num v1178] :=> v1178)) =
\(Main.l0.l0.n.DARG0 :: Ä) ->
(13 :: ([Prelude.Num t1] :=> t1))
in
(((Prelude.print :: ([Prelude.Show t4] :=> (t4 -> (Prelude.IO ()))))
(CompositDict ${Prelude.[] Prelude.Show} [${Prelude.Int Prelude.Show}])) $
(((Prelude.take :: (Prelude.Int -> ([t5] -> [t5])))
(5 :: ([Prelude.Num t6] :=> t6)))
let
(Main.l0.l0.l1.x :: [Prelude.Int]) =
(((Prelude.enumFrom :: ([Prelude.Enum t7] :=> (t7 -> [t7])))
${Prelude.Int Prelude.Enum})
(Main.l0.l0.n :: ([Prelude.Num v1178] :=> v1178)))
in
(Main.l0.l0.l1.x :: [Prelude.Int])))
次に、aseq2.hs:
(Main.main :: (Prelude.IO ())) =
let
(Main.l0.l0.n :: Prelude.Int) =
(13 :: ([Prelude.Num t0] :=> t0))
in
(((Prelude.print :: ([Prelude.Show t3] :=> (t3 -> (Prelude.IO ()))))
(CompositDict ${Prelude.[] Prelude.Show} [${Prelude.Int Prelude.Show}])) $
(((Prelude.take :: (Prelude.Int -> ([t4] -> [t4])))
(5 :: ([Prelude.Num t5] :=> t5)))
(((Prelude.enumFrom :: ([Prelude.Enum t6] :=> (t6 -> [t6])))
${Prelude.Int Prelude.Enum})
(Main.l0.l0.n :: Prelude.Int))))
aseq.hs の方では、n がなぜか 13 ではなく \$d -> 13 のような形になっている。 これを Show しようとして、ランタイムでアサーションに引っかかっていた。
これは、まったく、Arithmetic Sequence とは関係のないエラーだった。 次のようなサンプルコードでも再現:
main = print x where x = 13
これは、where 節の処理がおかしいわけではなく、本来、整数リテラルは fromInter 13 と同等であるはずなので、それを端折っているのがよくないと思われる。
別 Issue にして、本件は閉じよう。