#1897: Type families: type signature rejected
-------------------------------------+--------------------------------------
Reporter: guest | Owner: chak
Type: bug | Status: reopened
Priority: low | Milestone: 6.10 branch
Component: Compiler (Type checker) | Version: 6.9
Severity: normal | Resolution:
Keywords: | Difficulty: Unknown
Testcase: | Architecture: x86
Os: Linux |
-------------------------------------+--------------------------------------
Comment (by Isaac Dupree):
In this case I'd say something like "GHC can't figure out which class
instance you mean by the function's arguments or results' types"... or
let's see what an existing error says.
{{{
foo :: (Show a, Read a) => Int
foo = 1 where x = show (read "xxx")
}}}
{{{
ambig.hs:4:0:
Ambiguous constraint `Show a'
At least one of the forall'd type variables mentioned by the
constraint
must be reachable from the type after the '=>'
In the type signature for `foo':
foo :: (Show a, Read a) => Int
ambig.hs:4:0:
Ambiguous constraint `Read a'
At least one of the forall'd type variables mentioned by the
constraint
must be reachable from the type after the '=>'
In the type signature for `foo':
foo :: (Show a, Read a) => Int
}}}
Surely we can detect that? If there's something imprecise about "no use of
the actual type variable" (outside non-FD class constraints and TF
arguments)... See if the type unifies with a copy of itself, and if it
doesn't, it shouldn't be allowed?
How about
{{{
Ambiguous constraint `Depend a'
At least one of the forall'd type variables mentioned by the
constraint
must be reachable from the type after the '=>'
In the type signature for `isValid':
isValid :: (Bug s) => [Depend s] -> Bool
}}}
Admittedly "reachable" might confuse people who don't think about what it
means. It can be affected by equality constraints, for example. (is `foo
:: (a ~ Char, Show a, Read a) => Int; foo = 1` supposed to be rejected by
6.9? It is rejected with the same "Ambiguous constraint" message... and
is a useless type constraint, but not an ambiguous one per se) (but `foo
:: (a ~ Int) => F a -> F a; foo = id` is perfectly fine) (Also, in this
case, leaving `foldM next start ds` without a type-signature inside the
type-information-losing `isJust`, ensures that `isJust (foldM next start
ds)` has no usable type, for any `ds`.)
If we reject the explicit type signature of `foo :: F a -> F a; foo = id`
in that thread outright, then I thought we're safe in assuming that this
error will only appear in definitions that *do* have an explicit type-
signature (it won't be inferred), unlike the typeclass one without its
signature?:
{{{
foo = 1 where x = show (read "xxx")
}}}
{{{
ambig.hs:5:24:
Ambiguous type variable `a' in the constraints:
`Read a' arising from a use of `read' at ambig.hs:5:24-33
`Show a' arising from a use of `show' at ambig.hs:5:18-34
Probable fix: add a type signature that fixes these type variable(s)
}}}
But I might have been wrong: `isJust (foldM next start ds)` is just as bad
as `show . read`: but then, I think that relies on it also having a
typeclass constraint that's ambiguous, because you can introduce *that*
without an explicit type-signature.
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/1897#comment:5>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs