Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Overlapping pragmas #84

Closed
wants to merge 1 commit into from
Closed

Conversation

treeowl
Copy link
Contributor

@treeowl treeowl commented Feb 22, 2016

Use a closed type family to avoid the need for overlapping
instances. This shouldn't really affect anything, but
it makes instance selection more explict.

Use a closed type family to avoid the need for overlapping
instances. This shouldn't really affect anything, but
it makes instance selection more explict.
@treeowl
Copy link
Contributor Author

treeowl commented Feb 22, 2016

Hmm... This actually seems to prevent some things from working. Some things that maybe shouldn't work? I need to consider this a bit more.

@treeowl
Copy link
Contributor Author

treeowl commented Feb 22, 2016

Specifically, GHC seems happy to fall back on the overlapping "not this one" instance quite readily when confronted with the question of whether, e.g., a ~ (a,b). However, it's more conservative about type family reduction out of fear of type families that loop and thus can produce infinite types like (a,(a,(a,..... But this affects the type accepted for, e.g., \a b -> genericShrink (a, b). It's not clear to me whether this can actually cause problems for realistic uses of genericShrink.

@nick8325
Copy link
Owner

Hi,

It is quite worrying if genericShrink can miss shrink candidates because of GHC picking the wrong instance. Do you have an example (even if it's artificial) where this can happen? I'd like to understand this better.

Note that a ~ (a, b) is indeed impossible because the only solutions are infinite types. So GHC is right to pick the other instance in this case.

I can't merge this change directly because closed type families are only supported from GHC 7.8 upwards. But if there are cases where GHC picks the wrong instance with OverlappingInstances, then we could use the preprocessor to select either this implementation or the existing one depending on the GHC version.

@treeowl
Copy link
Contributor Author

treeowl commented Feb 23, 2016

I don't actually know if this can go wrong. Type family reduction is very conservative because GHC can't always recognize infinite types. You can write

type family Ugh a where
   Ugh a = (a, Ugh a)

This can, of course, throw the type checker into an infinite loop when it's reduced, which is okay. But the existence of such families precludes GHC from implementing a general a /~ (a,b) rule, so when you apply

type family (==) a b where
  a == a = 'True
  a == b = 'False

as a == (a,b) for unknown a, it refuses to reduce and considers itself stuck. This is (at least for now) necessary to maintain type safety. The overlapping instance mechanism is more liberal. It seems satisfied to conclude that they're not equal and select the more general instance. This, at worst, risks incoherence, but not type safety failure.

@treeowl
Copy link
Contributor Author

treeowl commented Feb 23, 2016

I prefer closed type families to overlapping instances as a matter of taste (though I don't really love either). It would, I think, take some experimentation to determine whether the type family implementation reduces under circumstances typical for Arbitrary instances.

@nick8325
Copy link
Owner

Yikes, I see. That's quite nasty!

I also prefer closed type families to overlapping instances. But I don't want to break QuickCheck on GHC 7.6 (still the default version on e.g. Debian stable) so let's make this change in the future.

@MaximilianAlgehed
Copy link
Collaborator

Closing this as completed via #370

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants