lookup_gset_to_gmap: use decide rather than guard
guard
is parsing-only notation (which is inherently confusing when comparing the goal state with the Coq sources) and rather rare. decide
is a lot more common, and so people are more likely to know how to deal with it.
Merge request reports
Activity
Hm I guess there is a question whether it makes sense to do this for just one of the uses of
guard
. If we agreeguard
is confusing we should probably remove it entirely. Or otherwise we should try to find ways to improve it.- Maybe make the notation also printing?
- I didn't even know about
case_option_guard
. Instead of having 3 tactics for almost the same thing (case_decide
,case_bool_decide
,case_option_guard
), can we have one tactic for all of them? I think I even triedcase_decide
when I had my trouble withmguard
, but it did not work.
Ideally guard would not have a continuation, but should just have type
∀ P `{!Decision P}, M P
Then you can chain it with bind. I think back in the days there was some technical issue preventing this, so we have to try that again.
Edited by Robbert KrebbersSeparately, instead of having an
MGuard
typeclass, what about havingMFail
orEmpty
, like in the following?Definition mguard `{Empty (M P), MRet M} P `{Decision P} := match decide P with | left H => mret H | right _ => mfail end.
That could subsume
option_guard
andset_guard
. (I first usedempty
formfail
, but I see addingEmpty option := None
would be odd).I like @Blaisorblade's proposal.
I think having an
MFail
makes sense, usingEmpty
is a bit like repurposingSingleton
for return.Ralf: My argument is that lawless instances seem problematic, that the laws for
Empty
come fromSet_
orFinMap
, and neither is a clear fit foroption
. Otherwise you risk needingSet Printing All
just to find how to reason about the∅
in your goal. But I thought I was inferring this idea, not making it up...Robbert:
Singleton = MRet
isn't that outrageous for collection monads (seeelem_of_ret {A} (x y : A) : x ∈@{M A} mret y ↔ x = y;
).And I'd consider extending
MonadSet
withnot_elem_of_fail' : ~(x ∈{M A} mfail)
, then derivingnot_elem_of_fail : x ∈{M A} mfail <-> False
.
mentioned in issue #171