[#854] Make WithDeMorganScope instances more principled
Description
Make WithDeMorganScope
instances more principled, avoiding a non-compiler-checked "impossible" error.
Related issue(s)
Retain type information for a bit longer to let GHC check our work in withDeMorganScope
instances.
Resolves #854 (closed)

Checklist for your Merge Request

Related changes (conditional)
-
Tests (see short guidelines)
-
If I added new functionality, I added tests covering it. -
If I fixed a bug, I added a regression test to prevent the bug from silently reappearing again.
-
-
Documentation
Stylistic guide (mandatory)
-
My commits comply with the following policy. -
My code complies with the style guide.
Merge request reports
Activity
added 1 commit
- 330d102f - [#854 (closed)] Make WithDeMorganScope instances more principled
changed title from [#854 (closed)] Make WithDeMorgan instances more principled to [#854 (closed)] Make WithDeMorganScope instances more principled
marked the checklist item My code complies with the style guide. as completed
marked the checklist item My commits comply with the following policy. as completed
marked the checklist item Root README and other
README.md
files as completedmarked the checklist item docs/ as completed
- Resolved by David Feuer
This change is not externally visible. How do I satisfy the CI bot without a changelog entry?
requested review from @pasqu4le and @lierdakil
1050 1045 instance (SingI a, SingI b) => WithDeMorganScope HasNoOp 'TPair a b where 1051 withDeMorganScope = mkWithDeMorgan @HasNoOp @a @b 1046 withDeMorganScope f 1047 | Refl <- orL @(ContainsOp a) @(ContainsOp b) 1048 , Refl <- orR @(ContainsOp a) @(ContainsOp b) 1049 = f 1050 1051 orL :: (a || b) ~ 'False => a :~: 'False 1052 orL = unsafeCoerce Refl 1053 1054 orR :: (a || b) ~ 'False => b :~: 'False 1055 orR = unsafeCoerce Refl 1056 1057 We'd presumably want to use RULES to rewrite more principled instances 1058 to do this sort of thing instead. But can we do it reasonably nicely 1059 without hand-writing two implementations for each instance? Let's take
HasNoOp t
as an example. We have an instance ifContainsOp t ~ 'False
-- which we can conjure into existence from thin air withunsafeCoerce
. For it to be safe, we need to be sure thatContainsOp t
indeed evaluates toFalse
, but that will be verified by the inefficient code. And the efficient code essentially boils down tounsafeWithDeMorganScope f = case (unsafeCoerce Refl :: ContainsOp t :~: 'False) of Refl -> f
which we can generalize using type applications to accept the family we need to
unsafeCoerce
as a parameter. Which we can then directly use in rule definitions. So, one ambiguous polymorphic helper function and one rule per instance with explicit type binders.I'm sure there are some gotchas, but at first glance this seems workable?
Edited by Nikolay YakimovIf we're going to do something unsafe, I'd prefer to keep the trusted base as small as possible, as in
OrL
andOrR
. So I'm imagining maybe asingletons
-like defunctionalization of the type families so we can talk about ideas like "The passed type family works like this when passed this sort of structure with these substructures"."Unsafe" is a relative term here. As long as GHC actually uses the "inefficient but verifiable" implementation to typecheck everything and then substitutes the appropriate "unsafe" one, the "unsafe" one is as safe as the "inefficient" one. One possible gotcha I see here is a mistake in rewriting rules would end up in a segfault. But that's something we'll have to make peace with regardless.
changed this line in version 3 of the diff
- Resolved by David Feuer
@lierdakil The test failure in https://gitlab.com/morley-framework/morley/-/jobs/2898171237 is very troubling. I can't imagine that this change has anything to do with it; is there something known to be fragile or did we just hit a lucky test case and discover a problem?
added 1 commit
- f97d3071 - [#854 (closed)] Make WithDeMorganScope instances more principled
added 1 commit
- 372bf978 - fixup! [#854 (closed)] Make WithDeMorganScope instances more principled
marked this merge request as draft from 372bf978
added 1 commit
- 1dad23e5 - [#854 (closed)] Make WithDeMorganScope instances more principled