types do not unify: (TCon (Tycon "Prelude.Int" Star),TCon (Tycon "Prelude.Integer" Star)) となるような小さなケースを作って調査する。
$ ./test-compile.sh testcases/intlit.hs source file: testcases/intlit.hs dst dir: /intlit doCompile ... done. implicitPrelude ... done. doCompile ... bunnyc: types do not unify: (TCon (Tycon "Prelude.Int" Star),TCon (Tycon "Prelude.Integer" Star))
intlit.hs :
f :: Int -> IO () f x = print x main = f 10
Core0:
---- ddumpCore ---- (Main.main :: (Prelude.IO ())) = ((Main.f :: (Prelude.Int -> (Prelude.IO ()))) (10 :: Prelude.Integer)) (Main.f :: (Prelude.Int -> (Prelude.IO ()))) = \(_Main.f.U1 :: Prelude.Int) -> ((Prelude.print :: ([Prelude.Show t0] :=> (t0 -> (Prelude.IO ())))) (_Main.f.U1 :: Prelude.Int)) bunnyc: types do not unify: (TCon (Tycon "Prelude.Int" Star),TCon (Tycon "Prelude.Integer" Star))
整数リテラルの 10 が (10 :: Prelude.Integer) なのがおかしい。 だれだ、こんなことをしたのは。
trCore にあった:
trExpr2 (Ty.Lit (Ty.LitInt n)) = return e where e = Lit $ LitInt n tInteger
Typing.tiLit がやっているように、Num a => a にしなければいけない:
tiLit (LitInt _) = do v <- newTVar Star return ([IsIn "Prelude.Num" v], v)
まず、Core 言語の仕様として、Literal に Type しかついていなかったので、 これを Qual Type に変える。まずそれだけ変更して、make check パスすることを確認。
つぎに、整数リテラルにつける型を変える。
trExpr2 (Ty.Lit (Ty.LitInt n)) = do v <- newTVar' Star return (Lit (LitInt n ([IsIn "Prelude.Num" v] :=> v)))
そうすると、intlit.hs は通るようになったが、make check で 15/64 tests failed になった。
ただ、これは、DictPass の段階で defaulting しないといけないのだと思う。 (ので、おそらくこれは、劣化ではなく、未実装機能の露見)
かなりその場しのぎの実装だが、DictPass における defaulting を実装して、 make check が通るようにした。この実装をまともにするのは、別の issue 045 とする。
以下の testcase が通るようになった:
本件と 001, 002, 022 はクローズ