Bump `base` version to 4.9.0.0 (closes #11026)
[ghc.git] / testsuite / tests / typecheck / should_fail / SCLoop.hs
1 {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
2
3 -- This is a superclass loop test
4 -- It should fail with a type error, but
5 -- it's all too easy to succeed with a bogus recursive dictionary
6
7 module SCLoop where
8
9 class SC a where
10 f :: a -> ()
11
12 class SC a => A a b where
13 op :: a -> b -> ()
14 op x _ = f x
15
16 instance A a b => A a [b]
17 -- dfun1 :: \d::(A a b) -> DA (sc d)
18
19 instance SC a => A a (Maybe b)
20 -- dfun2 :: \d::SC a -> DA d
21
22 foo = op () ([Just True])
23
24 {- Here is the explanation:
25 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
26
27 [Wanted] d1 : (A () [Maybe Bool])
28 ~~~> d1 := dfun1 d2
29 [Wanted] d2 : (A () (Maybe Bool))
30 ~~~> d2 := dfun2 d3
31 [Wanted] d3 : SC ()
32 [Derived] d4 : SC () d4 := sc d1
33 ~~~>
34 d3 := sc d1
35 isGoodRecEv will check:
36 d3 == sc d1
37 == sc (dfun1 d2)
38 == sc (dfun1 (dfun2 d3) ==> PASSES! (gravity = 1)
39 This is BAD BAD BAD, because we get a loop
40
41 If we had inlined the definitions:
42 d3 == sc d1
43 == sc (DA (sc d2))
44 == sc (DA (sc (DA d3))) ==> DOES NOT! (gravity = 0)
45
46 We should get "No instance for SC ()"
47 -}
48
49
50
51
52
53
54
55