instance 宣言における型変数の出現順序に関するもの。以下のプログラムがエラーとなる:
data Pair a b = Pair a b instance (Show a, Show b) => Show (Pair b a) where show (Pair x y) = "Pair " ++ show x ++ " " ++ show y main = print (Pair 1 'x')
bunny 0.9.0 での実行結果:
$ bunny testrun contextorder2.hs
/home/unno/bunny/0.9.0/bin/bunnyc -d ./jout/contextorder2 --xno-implicit-prelude /home/unno/bunny/0.9.0/lib/Prelude.hs
/home/unno/bunny/0.9.0/bin/bunnyc -d ./jout/contextorder2 --xlibrary-path /home/unno/bunny/0.9.0/lib contextorder2.hs
Not a BoxedCharObj:AtomExpr(a=Var(obj=1 :: Integer))
Exception in thread "main" java.lang.AssertionError
at jp.ne.sakura.uhideyuki.brt.runtime.RTLib.toJString(RTLib.java:98)
at jp.ne.sakura.uhideyuki.brt.runtime.PutStrLnFunc.call(RTLib.java:29)
at jp.ne.sakura.uhideyuki.brt.runtime.EvalApply.evalFun(RT.java:243)
at jp.ne.sakura.uhideyuki.brt.runtime.EvalApply.runStep(RT.java:60)
at jp.ne.sakura.uhideyuki.brt.runtime.EvalApply.eval(RT.java:18)
at jp.ne.sakura.uhideyuki.brt.runtime.RT.eval(RT.java:292)
at Sample.main(Sample.java:6)
--ddump-core してみる。
Pair 向け Show の実体では、辞書を a, b の順番でうけとって、つかうのは b, a 順となっている:
(Main.Pair%I.show :: ([Prelude.Show t64,Prelude.Show t65] :=> (((Main.Pair t65) t64) -> [Prelude.Char]))) =
\(Main.Pair%I.show.DARG0 :: Ä) (Main.Pair%I.show.DARG1 :: Ä) ->
\(_Main.Pair%I.show.U1 :: ([Prelude.Show t50,Prelude.Show t51] :=> ((Main.Pair t51) t50))) ->
case (_Main.Pair%I.show.U1 :: ([Prelude.Show t50,Prelude.Show t51] :=> ((Main.Pair t51) t50))) (_Main.Pair%I.show.U1b :: ([Prelude.Show t50,Prelude.Show t51] :=> ((Main.Pair t51) t50))) of
Main.Pair (_Main.Pair%I.show.U2 :: t52) (_Main.Pair%I.show.U3 :: t53) :: (t52 -> (t53 -> ((Main.Pair t52) t53))) ->
(((Prelude.++ :: ([t55] -> ([t55] -> [t55])))
"Pair ")
(((Prelude.++ :: ([t56] -> ([t56] -> [t56])))
(((Prelude.show :: ([Prelude.Show t57] :=> (t57 -> [Prelude.Char])))
(Main.Pair%I.show.DARG1 :: Å))
(_Main.Pair%I.show.U2 :: t52)))
(((Prelude.++ :: ([t60] -> ([t60] -> [t60])))
" ")
(((Prelude.show :: ([Prelude.Show t61] :=> (t61 -> [Prelude.Char])))
(Main.Pair%I.show.DARG0 :: Å))
(_Main.Pair%I.show.U3 :: t53)))))
一方、渡す側では Pair に渡す順番で CompositDict を構成している:
(Main.main :: (Prelude.IO Prelude.())) =
(((Prelude.print :: ([Prelude.Show t1] :=> (t1 -> (Prelude.IO Prelude.()))))
(CompositDict ${Main.Pair Prelude.Show} [${Prelude.Integer Prelude.Show},${Prelude.Char Prelude.Show}]))
(((Main.Pair :: (t2 -> (t3 -> ((Main.Pair t2) t3))))
(((Prelude.fromInteger :: ([Prelude.Num t4] :=> (Prelude.Integer -> t4)))
${Prelude.Integer Prelude.Num})
(1 :: Prelude.Integer))) 'x'))
これ、Rename の段階で instance (Show a, Show b) => Show (Pair b a) where を instance (Show b, Show a) => Show (Pair b a) where に書き換えてやれば、つじつまが合うんじゃないかな。
全件確認シリーズ:
unno@unno-FMVD70GN7G ~/work/bissues/051
$ cat contextorder2.hs
data Pair a b = Pair a b
instance (Show a, Show b) => Show (Pair b a) where
show (Pair x y) = "Pair " ++ show x ++ " " ++ show y
main = print (Pair 1 'x')
unno@unno-FMVD70GN7G ~/work/bissues/051
$ runhaskell contextorder2.hs
Pair 1 'x'
unno@unno-FMVD70GN7G ~/work/bissues/051
$ ~/prj/bunny/compiler/bin/bunny testrun contextorder2.hs
/home/unno/prj/bunny/compiler/bin/bunnyc -d ./jout/contextorder2 --xno-implicit-prelude /home/unno/prj/bunny/compiler/bin/../lib/Prelude.hs
/home/unno/prj/bunny/compiler/bin/bunnyc -d ./jout/contextorder2 --xlibrary-path /home/unno/prj/bunny/compiler/bin/../lib contextorder2.hs
Not a BoxedCharObj:AtomExpr(a=Var(obj=1 :: Integer))
Exception in thread "main" java.lang.AssertionError
at jp.ne.sakura.uhideyuki.brt.runtime.RTLib.toJString(RTLib.java:98)
at jp.ne.sakura.uhideyuki.brt.runtime.PutStrLnFunc.call(RTLib.java:29)
at jp.ne.sakura.uhideyuki.brt.runtime.EvalApply.evalFun(RT.java:243)
at jp.ne.sakura.uhideyuki.brt.runtime.EvalApply.runStep(RT.java:60)
at jp.ne.sakura.uhideyuki.brt.runtime.EvalApply.eval(RT.java:18)
at jp.ne.sakura.uhideyuki.brt.runtime.RT.eval(RT.java:292)
at Sample.main(Sample.java:6)
ランタイムエラーになっているよう。