blob: f3f6a20bc4b3ebf9cf94722054b20a611a928dc0 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
{-# 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 ()"
-}
|