Desugaring matches with already-desugared RHSs?
Alexis King
lexi.lambda at gmail.com
Sun Apr 26 01:40:00 UTC 2020
Hi all,
I’m currently in the process of rewriting most of the arrow desugaring
code. One of the most awkward parts of the current implementation is
the way case commands are desugared. Given a case command like
case e1 of
A a b -> cmd1
B c -> cmd2
C d e f -> cmd3
the desugarer actually replaces each command on the RHS with an
Either-wrapped tuple to get something like this:
arr (\env -> case e1 of
A a b -> Left (Left (a, b))
B c -> Left (Right c)
C d e f -> Right (d, e, f))
>>> ((cmd1 ||| cmd2) ||| cmd3)
This means the RHSs of the case expression are really already
desugared, and ideally they would be CoreExprs, but matchWrapper
expects the RHSs to be HsExprs. The current implementation
accommodates this restriction by building fake HsExprs with no
location information, but this means the logic for building the tuples
in the RHSs has to be duplicated (since other places do want
CoreExprs).
I was thinking it would be nice to avoid this hack, but I’m not sure
what the best way to do it is. One way would be to create a variant of
matchWrapper with a type like
matchWrapper'
:: HsMatchContext GhcRn
-> Maybe (LHsExpr GhcTc)
-> MatchGroup GhcTc rhs
-> (rhs -> DsM CoreExpr) -- how to desugar the RHSs
-> DsM ([Id], CoreExpr)
and update dsGRHSs to accept an extra argument as well. Then the arrow
desugaring code could just pass `return` to matchWrapper' so it
wouldn’t touch its RHSs. But I’m not sure if this approach makes sense
— nothing else in the desugarer seems to work this way. Is there a
better approach I’m not seeing?
Thanks,
Alexis
More information about the ghc-devs
mailing list