Note [The no-tyvar no-dict case]
Suppose we are desugaring
AbsBinds { tyvars = []
, dicts = []
, exports = [ ABE f fm, ABE g gm ]
, binds = B
, ev_binds = EB }
That is: no type variables or dictionary abstractions. Here, `f` and `fm` are
the polymorphic and monomorphic versions of `f`; in this special case they will
both have the same type.
Specialising Note [Desugaring AbsBinds] for this case gives the desugaring
tup = letrec EB' in letrec B' in (fm,gm)
f = case tup of { (fm,gm) -> fm }
g = case tup of { (fm,gm) -> fm }
where B' is the result of desugaring B. This desugaring is a little silly: we
don't need the intermediate tuple (contrast with the general case where fm and f
have different types). So instead, in this case, we desugar to
EB'; B'; f=fm; g=gm
This is done in the `null tyvars, null dicts` case of `dsAbsBinds`.
But there is a wrinkle (DSB1). If the original binding group was
/non-recursive/, we want to return a bunch of non-recursive bindings in
dependency order: see Note [Return non-recursive bindings in dependency order].
But there is no guarantee that EB', the desugared evidence bindings, will be
non-recursive. Happily, in the non-recursive case, B will have just a single
binding (f = rhs), so we can wrap EB' around its RHS, thus:
fm = letrec EB' in rhs; f = fm
There is a sub-wrinkle (DSB2). If B is a /pattern/ bindings, it will desugar to
a "main" binding followed by a bunch of selectors. The main binding always
comes first, so we can pick it out and wrap EB' around its RHS. For example
AbsBinds { tyvars = []
, dicts = []
, exports = [ ABE p pm, ABE q qm ]
, binds = PatBind (pm, Just qm) rhs
, ev_binds = EB }
can desguar to
pt = let EB' in
case rhs of
(pm,Just qm) -> (pm,qm)
pm = case pt of (pm,qm) -> pm
qm = case pt of (pm,qm) -> qm
p = pm
q = qm
The first three bindings come from desugaring the PatBind, and subsequently
wrapping the RHS of the main binding in EB'.
Why got to this trouble? It's a common case, and it removes the
quadratic-sized tuple desugaring. Less clutter, hopefully faster
compilation, especially in a case where there are a *lot* of
bindings. References 2
- Desugaring AbsBinds GHC.HsToCore.Binds
- Return non-recursive bindings in dependency order GHC.HsToCore.Binds
Referenced by 2
- GHC.HsToCore.Binds call site ×2