You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
works :: (Apply Eq1 r, Eq v) => Sum r v -> Sum r v -> Bool
works x y = x == y
-- Could not deduce (Apply Eq1 (Const () : r))
fails :: (Apply Eq1 r, Eq v) => Sum r v -> Sum r v -> Bool
fails x y = weaken @_ @_ @(Const ()) x == weaken y
Of course, if I try to provide the missing instance it complains about overlap. So how do I convince it that if Apply Eq1 r, then clearly Apply Eq1 (Const () : r), since there is both Eq1 for Const and Eq for ()?
The key detail here is that it's complaining that it lacks the Apply instance, not Eq1 or Eq. Lacking the Apply instance (or rather, a constraint bringing it into scope) is the fault of the sad fact that Apply isn't inductive, so knowing either of Apply Eq1 r or Apply Eq1 (Const : r) is insufficient to deduce the other. That's unfortunately precisely why fastsum exists: by not defining properties inductively, we avoid ghc's problems with constraints under these conditions, which grow (IIRC) quadratically.
You can add a constraint for the instance you want, which in this example could replace the instance for r, but it is admittedly a bit gross to expose implementation details like that. I think what I used to do in cases like this was to operate on the un-weakened things wherever possible—weaken last, in other words—or equivalently to operate on the things to be inserted directly as long as possible before making a union. Of course, if I'm not in need of weakening, then there's really no problem.
Activity
patrickt commentedon Feb 8, 2022
Hm. This very much feels like it should work. I have no idea why it doesn't.
robrix commentedon Feb 24, 2022
The key detail here is that it's complaining that it lacks the
Applyinstance, notEq1orEq. Lacking theApplyinstance (or rather, a constraint bringing it into scope) is the fault of the sad fact thatApplyisn't inductive, so knowing either ofApply Eq1 rorApply Eq1 (Const : r)is insufficient to deduce the other. That's unfortunately precisely whyfastsumexists: by not defining properties inductively, we avoidghc's problems with constraints under these conditions, which grow (IIRC) quadratically.You can add a constraint for the instance you want, which in this example could replace the instance for
r, but it is admittedly a bit gross to expose implementation details like that. I think what I used to do in cases like this was to operate on the un-weakened things wherever possible—weakenlast, in other words—or equivalently to operate on the things to be inserted directly as long as possible before making a union. Of course, if I'm not in need ofweakening, then there's really no problem.Let us know how it goes!