[GHC] #16154: -Wredundant-constraints: False positive
GHC
ghc-devs at haskell.org
Thu Jan 10 16:13:43 UTC 2019
#16154: -Wredundant-constraints: False positive
-------------------------------------+-------------------------------------
Reporter: fumieval | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler (Type | Version: 8.6.3
checker) |
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: Incorrect | Unknown/Multiple
error/warning at compile-time | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by simonpj):
Interesting. Consider these three possible type signatures for `id`:
{{{
id x = x
}}}
1. `id :: forall a. a -> a`: the most general type
2. `id :: Int -> Int`: not the most general type, by any means, but
accepted without warnng.
3. `id :: Num a => a -> a`: not the most general type, although more
general than `Int -> Int`. Elicits a redundant constraint warning.
Arguably, it's odd that (2) is accepted without complaint, whereas (3)
elicits a warning.
Still, in the case of `id` there is no reason to prefer (3) over (1). But
your example shows that it is, in fact,
sometimes desirable to have a constraint that is not used (as in `id`).
Here is a small contrived example:
{{{
-- f :: (a ~ Bool) => a -> Int
f :: a -> Int
f x = 3
g :: String -> Int
g s = f (read s)
}}}
Here the type of `y` is unconstrained, but we need to know what it is to
resolve the Read constraint.
If `f :: a -> Int`, there is no way to resolve the ambiguity, so we get
{{{
Foo.hs:38:10: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘read’
prevents the constraint ‘(Read a0)’ from being solved.
}}}
But if we give `f` the signature `f :: (a ~ Bool) => a -> Int`,the
ambiguity goes away; it is resolved to `Bool`.
But instead we get
{{{
Foo.hs:33:1: warning: [-Wredundant-constraints]
• Redundant constraint: a ~ Bool
• In the type signature for:
f :: forall a. (a ~ Bool) => a -> Int
|
33 | f :: (a ~ Bool) => a -> Int
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
}}}
Your example is similar, but a little more complicated.
I'm not sure what to say. The constraint ''is'' redundant for `f`'s
definition. And yet a
less-general (more constrained) type can aid the caller.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/16154#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list