Instance Wrapping #
Both inferInstanceAs and the default deriving handler wrap instance bodies to ensure
that when deriving or inferring an instance for a semireducible type definition, the
definition's RHS is not leaked when reduced at lower than semireducible transparency.
Algorithm #
Given an instance i : I and expected type I' (where I' must be mvar-free),
wrapInstance constructs a result instance as follows, executing all steps at
instances transparency:
- If
I'is not a class, returniunchanged. - If
I'is a proposition, wrapiin an auxiliary theorem of typeI'and return it (controlled bybackward.inferInstanceAs.wrap.instances). - Reduce
ito whnf. - If
iis not a constructor application: if the type ofiis already defeq toI', returni; otherwise wrap it in an auxiliary definition of typeI'and return it (controlled bybackward.inferInstanceAs.wrap.instances). - Otherwise, for
i = ctor a₁ ... aₙwithctor : C ?p₁ ... ?pₙ:- Unify
C ?p₁ ... ?pₙwithI'. - Return a new application
ctor a₁' ... aₙ' : I'where eachaᵢ'is constructed as:- If the field type is a proposition: assign directly if types are defeq, otherwise wrap in an auxiliary theorem.
- If the field type is a class: first try to reuse an existing synthesized instance
for the target type (controlled by
backward.inferInstanceAs.wrap.reuseSubInstances); if that fails, recurse with source instanceaᵢand expected type?pᵢ. - Otherwise (data field): assign directly if types are defeq, otherwise wrap in an
auxiliary definition to fix the type (controlled by
backward.inferInstanceAs.wrap.data).
- Unify
Options #
backward.inferInstanceAs.wrap: master switch for wrapping in bothinferInstanceAsand the defaultderivinghandlerbackward.inferInstanceAs.wrap.reuseSubInstances: reuse existing instances for sub-instance fields to avoid non-defeq instance diamondsbackward.inferInstanceAs.wrap.instances: wrap non-reducible instances in auxiliary definitionsbackward.inferInstanceAs.wrap.data: wrap data fields in auxiliary definitions
Rebuild a type application with fresh synthetic metavariables for instance-implicit arguments. Non-instance-implicit arguments are assigned from the original application's arguments. If the function is over-applied, extra arguments are preserved.
Equations
- One or more equations did not get rendered due to their size.