Commit 4a41098a authored by Simon Peyton Jones's avatar Simon Peyton Jones
Browse files

Another, simple, superclass loop test

parent 4b8bfc51
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
-- This is a superclass loop test
-- It should fail with a type error, but
-- it's all too easy to succeed with a bogus recursive dictionary
module SCLoop where
class SC a where
f :: a -> ()
class SC a => A a b where
op :: a -> b -> ()
op x _ = f x
instance A a b => A a [b]
-- dfun1 :: \d::(A a b) -> DA (sc d)
instance SC a => A a (Maybe b)
-- dfun2 :: \d::SC a -> DA d
foo = op () ([Just True])
{- Here is the explanation:
~~~~~~~~~~~~~~~~~~~~~~~~~~~
[Wanted] d1 : (A () [Maybe Bool])
~~~> d1 := dfun1 d2
[Wanted] d2 : (A () (Maybe Bool))
~~~> d2 := dfun2 d3
[Wanted] d3 : SC ()
[Derived] d4 : SC () d4 := sc d1
~~~>
d3 := sc d1
isGoodRecEv will check:
d3 == sc d1
== sc (dfun1 d2)
== sc (dfun1 (dfun2 d3) ==> PASSES! (gravity = 1)
This is BAD BAD BAD, because we get a loop
If we had inlined the definitions:
d3 == sc d1
== sc (DA (sc d2))
== sc (DA (sc (DA d3))) ==> DOES NOT! (gravity = 0)
We should get "No instance for SC ()"
-}
SCLoop.hs:22:7:
No instance for (SC ())
arising from a use of `op'
Possible fix: add an instance declaration for (SC ())
In the expression: op () ([Just True])
In an equation for `foo': foo = op () ([Just True])
......@@ -225,3 +225,4 @@ test('T3468', extra_clean(['T3468.hi-boot']),
multimod_compile_fail, ['T3468', '-v0'])
test('T2846b', normal, compile_fail, [''])
test('FrozenErrorTests', normal, compile_fail, [''])
test('SCLoop', normal, compile_fail, [''])
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment