Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#11582 closed bug (invalid)

Redundant constraints warning complains that (a ~ b) is redundant

Reported by: bgamari Owned by:
Priority: normal Milestone: 8.0.1
Component: Compiler (Type checker) Version: 8.0.1-rc2
Keywords: Cc: Lemming
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Incorrect warning at compile-time Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

Lemming came up with an interesting example where the redundant constraints warning is arguable a bit too trigger-happy in #10635. Consider,

asTypeOf :: a -> a -> a
asTypeOf x _ = x

We could equivalently rewrite this with an equality constraint,

asTypeOf1 :: (a ~ b) => a -> b -> a
asTypeOf1 x _ = x

If compiled with GHC 8.0 with -Wredundant-constraints we see a warning,

hi.hs:4:1: warning:
    • Redundant constraint: a ~ b
    • In the type signature for:
           asTypeOf1 :: (a ~ b) => a -> b -> a

But is this really unused? We may not have referenced the constraint in the RHS, but surely the typechecker has gleaned something from it.

Perhaps we should simply ignore equality constraints when generating redundant constraint warnings?

Change History (3)

comment:1 Changed 4 years ago by simonpj

Resolution: invalid
Status: newclosed

I don't agree. "Redundant" means that if you leave it off the function will still compile. And indeed

asTypeOf1 :: a -> b -> a
asTypeOf1 x _ = x

is just fine. So I don't know what you mean by saying "the type checker has gleaned something from it".

I say it's behaving precisely as advertised, so I'll close as invalid. Re-open if I have misunderstood.

comment:2 Changed 4 years ago by Lemming

I thought a bit about it and found that equality constraints and type class constraints actually differ in the following aspect: If you remove a redundant type class constraint from a function type signature then any code depending on that function will continue to be type correct and continue to work as before. In contrast to that, if you remove an equality constraint (or generalize a function like asTypeOf to a more general type), then code might no longer pass the type checker because of ambiguous types. That is, if you eagerly remove all redundant constraints then removed type class constraints will not do any harm but removed equality constraints might do so.

comment:3 Changed 4 years ago by simonpj

I see. Yes that is true. Sort of. Removing a type class with functional dependencies might have the same effect. Or a type class with a superclass that had functional depencies. Or a type class with a superclass equality like

class (a~b) => C a b where ...

And with higher-kinded stuff I don't think we can predict with precision.

I suppose you could have -fwarn-redundant-constraints-for-definition and -fwarn-redundant-constraints-for-call-sites, to say what level of redundancy you wanted to report or at least make best-efforts to report (see above).

But I do see what you mean, and it might be good to have such an example in the user manual.

Also if you felt like implementing per-signature control that would be cool.

Note: See TracTickets for help on using tickets.