[GHC] #3017: Type inference is broken when dealing with tuple type
synonyms
GHC
trac at galois.com
Wed Feb 11 07:19:30 EST 2009
#3017: Type inference is broken when dealing with tuple type synonyms
-------------------------+--------------------------------------------------
Reporter: straka.milan | Owner:
Type: bug | Status: new
Priority: normal | Component: Compiler
Version: 6.10.1 | Severity: normal
Keywords: | Testcase:
Os: Linux | Architecture: x86
-------------------------+--------------------------------------------------
I have GHC 6.10.1 built from the sources. In the whole bugreport, suppose
we have
{{{
{-# LANGUAGE TypeFamilies #-}
class Coll c where
type Elem c
empty :: c
insert :: Elem c -> c -> c
data ListColl a = L [a]
instance Coll (ListColl a) where
type Elem (ListColl a) = a
empty = L []
insert x (L xs) = L (x:xs)
emptyL :: ListColl a
emptyL = empty
}}}
GHCI says
{{{
test1 c = insert 0 c
test2 c = insert (0, 0) c
*Main> :t test1
test1 :: (Num (Elem c), Coll c) => c -> c
*Main> :t test2
test2 :: ((Integer, Integer) ~ Elem c, Coll c) => c -> c
}}}
Shouldn't be the type of test2 be something like
{{{test2 :: (Num a, Num b, (a, b) ~ (Elem c), Coll c) => c -> c}}}
?
When trying
{{{
test1 c = insert 0 c
test2 c = insert (0, 0) c
test3 :: ListColl (Float, Float)
test3 = test2 emptyL
}}}
we get
{{{
*Main> :t test2
test2 : ((Float, Float) ~ Elem c, Coll c) => c -> c
}}}
and
{{{
test1 c = insert 0 c
test2 c = insert (0, 0) c
test3 :: ListColl (Float, Float)
test3 = test2 emptyL
test3':: ListColl (Int, Int)
test3'= test2 emptyL
Couldn't match expected type `Int' against inferred type `Float'
Expected type: Elem (ListColl (Int, Int))
Inferred type: (Float, Float)
When generalising the type(s) for `test3''
Failed, modules loaded: none.
}}}
and
{{{
test1 c = insert 0 c
test2 c = insert (0, 0) c
test4::(Num a, Num b) => ListColl (a, b)
test4 = test2 empty
Inferred type is less polymorphic than expected
Quantified type variable `b' escapes
Quantified type variable `a' escapes
When trying to generalise the type inferred for `test4'
Signature type: forall a b. (Num a, Num b) => ListColl (a, b)
Type to generalise: ListColl (a, b)
In the type signature for `test4'
When generalising the type(s) for `test4'
Failed, modules loaded: none.
}}}
When adding explicit type signature
{{{test2 :: (Num a, Num b, (a, b) ~ (Elem c), Coll c) => c -> c}}}
all above examples works correctly, even if GHCI still says
{{{
:t test2
*Main> :t test2
test2 :: ((Integer, Integer) ~ Elem c, Coll c) => c -> c
}}}
Last weird thing is
{{{
test5 _ = insert 0 emptyL
*Main> :t test5
test5 :: (Num a) => t -> ListColl a
test6 _ = insert (0,0) emptyL
Ambiguous type variable `t' in the constraint:
`Num t'
arising from the literal `0'
at /work/skola/haskell/grafy/Bug.hs:32:18
Probable fix: add a type signature that fixes these type variable(s)
Ambiguous type variable `t1' in the constraint:
`Num t1'
arising from the literal `0'
at /work/skola/haskell/grafy/Bug.hs:32:21
Probable fix: add a type signature that fixes these type variable(s)
Failed, modules loaded: none.
}}}
but adding
{{{
test6 :: (Num a, Num b, (a, b) ~ (Elem (ListColl c)), Coll (ListColl c))
=> foo -> (ListColl c)
test6 _ = insert (0,0) emptyL
}}}
once again solves the problem.
Is this really a bug or just a feature :) I understand that in t1 ~ t2,
the t1 and t2 can be arbitraty monotypes, so (a, b) should work, even with
Num a and Num b, right?
Cheers,
Milan Straka
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/3017>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the Glasgow-haskell-bugs
mailing list