1 {-# OPTIONS -fglasgow-exts #-}
3 -- !!! Functional dependency test. Hugs [Apr 2001] fails to typecheck this
4 -- Rather bizarre example submitted by Jonathon Bell
6 module ShouldCompile where
8 class Bug f a r | f a -> r where
11 instance Bug (Int->r) Int r
12 instance (Bug f a r) => Bug f (c a) (c r)
14 f:: Bug(Int->Int) a r => a->r
15 f = bug (id::Int->Int)
18 -- Inner f gives result type
19 -- f [0::Int] :: Bug (Int->Int) [Int] r => r
20 -- Which matches the second instance declaration, giving r = [r']
21 -- f [0::Int] :: Bug (Int->Int) Int r' => r'
22 -- Wwich matches the first instance decl giving r' = Int
24 -- The outer f now has constraint
25 -- Bug (Int->Int) Int r
29 g2 = f (f (f [0::Int]))
30 -- The outer f repeats the exercise, so g2::Int
31 -- This is the definition that Hugs rejects
33 -- Here is a similar definition rejected by Hugs
34 -- It complains that the instances are not consistent with the
35 -- functional dependencies, which isn't true, because
36 -- (c a) does not unify with (c' a', c' b')
38 class Foo f a r | f a->r where
41 instance Foo (a->r) (c a) (c r)
42 instance Foo ((a,b)->r) (c a,c b)(c r)