[project @ 2001-05-03 08:35:33 by simonpj]
[ghc-hetmet.git] / ghc / tests / typecheck / should_compile / tc126.hs
1 {-# OPTIONS -fglasgow-exts #-}
2
3 -- !!! Functional dependency test. Hugs [Apr 2001] fails to typecheck this
4 -- Rather bizarre example submitted by Jonathon Bell
5
6 module ShouldCompile where
7
8 module Foo where
9
10 class Bug f a r | f a -> r where
11    bug::f->a->r
12
13 instance                Bug (Int->r) Int      r
14 instance (Bug f a r) => Bug f        (c a)    (c r) 
15
16 f:: Bug(Int->Int) a r => a->r
17 f = bug (id::Int->Int)
18
19 g1 = f (f [0::Int])
20 -- Inner f gives result type 
21 --      f [0::Int] :: Bug (Int->Int) [Int] r => r
22 -- Which matches the second instance declaration, giving r = [r']
23 --      f [0::Int] :: Bug (Int->Int) Int r' => r'
24 -- Wwich matches the first instance decl giving r' = Int
25 --      f [0::Int] :: Int
26 -- The outer f now has constraint
27 --      Bug (Int->Int) Int r
28 -- which makes r=Int
29 -- So g1::Int
30
31 g2 = f (f (f [0::Int]))
32 -- The outer f repeats the exercise, so g2::Int
33 -- This is the definition that Hugs rejects
34
35 -- Here is a similar definition rejected by Hugs
36 -- It complains that the instances are not consistent with the
37 -- functional dependencies, which isn't true, because
38 --      (c a) does not unify with (c' a', c' b')
39
40 class Foo f a r | f a->r where
41       foo::f->a->r
42
43 instance Foo (a->r)     (c a)    (c r)
44 instance Foo ((a,b)->r) (c a,c b)(c r)