doc: document some Deriving utils

This commit is contained in:
Wojciech Nawrocki 2022-04-23 19:13:07 -04:00 committed by Leonardo de Moura
parent 4b3c2b1790
commit aa5fe5864a
2 changed files with 19 additions and 3 deletions

View file

@ -14,6 +14,11 @@ def DerivingHandlerNoArgs := (typeNames : Array Name) → CommandElabM Bool
builtin_initialize derivingHandlersRef : IO.Ref (NameMap DerivingHandler) ← IO.mkRef {}
/-- A `DerivingHandler` is called on the fully qualified names of all types it is running for
as well as the syntax of a `with` argument, if present.
For example, `deriving instance Foo with fooArgs for Bar, Baz` invokes
``fooHandler #[`Bar, `Baz] `(fooArgs)``. -/
def registerBuiltinDerivingHandlerWithArgs (className : Name) (handler : DerivingHandler) : IO Unit := do
unless (← initializing) do
throw (IO.userError "failed to register deriving handler, it can only be registered during initialization")
@ -21,6 +26,7 @@ def registerBuiltinDerivingHandlerWithArgs (className : Name) (handler : Derivin
throw (IO.userError s!"failed to register deriving handler, a handler has already been registered for '{className}'")
derivingHandlersRef.modify fun m => m.insert className handler
/-- Like `registerBuiltinDerivingHandlerWithArgs` but ignoring any `with` argument. -/
def registerBuiltinDerivingHandler (className : Name) (handler : DerivingHandlerNoArgs) : IO Unit := do
registerBuiltinDerivingHandlerWithArgs className fun typeNames _ => handler typeNames

View file

@ -13,9 +13,9 @@ def implicitBinderF := Parser.Term.implicitBinder
def instBinderF := Parser.Term.instBinder
def explicitBinderF := Parser.Term.explicitBinder
/-- Make fresh, hygienic names for every parameter and index of an inductive
declaration. For example, `inductive Foo {α : Type} : Nat → Type` will give
something like `#[α✝, a✝]`. -/
/-- Make fresh, hygienic names for every parameter and index of an inductive declaration.
For example, `inductive Foo {α : Type} : Nat → Type` will give something like ``#[`α✝, `a✝]``. -/
def mkInductArgNames (indVal : InductiveVal) : TermElabM (Array Name) := do
forallTelescopeReducing indVal.type fun xs _ => do
let mut argNames := #[]
@ -25,15 +25,25 @@ def mkInductArgNames (indVal : InductiveVal) : TermElabM (Array Name) := do
argNames := argNames.push paramName
pure argNames
/-- Return the inductive declaration's type applied to the arguments in `argNames`. -/
def mkInductiveApp (indVal : InductiveVal) (argNames : Array Name) : TermElabM Syntax :=
let f := mkIdent indVal.name
let args := argNames.map mkIdent
`(@$f $args*)
/-- Return implicit binder syntaxes for the given `argNames`. The output matches `implicitBinder*`.
For example, ``#[`foo,`bar]`` gives `` `({foo} {bar})``. -/
def mkImplicitBinders (argNames : Array Name) : TermElabM (Array Syntax) :=
argNames.mapM fun argName =>
`(implicitBinderF| { $(mkIdent argName) })
/-- Return instance binder syntaxes binding `className α` for every generic parameter `α`
of the inductive `indVal` for which such a binding is type-correct. `argNames` is expected
to provide names for the parameters (see `mkInductArgNames`). The output matches `instBinder*`.
For example, given `inductive Foo {α : Type} (n : Nat) : (β : Type) → Type`, where `β` is an index,
invoking ``mkInstImplicitBinders `BarClass foo #[`α, `n, `β]`` gives `` `([BarClass α])``. -/
def mkInstImplicitBinders (className : Name) (indVal : InductiveVal) (argNames : Array Name) : TermElabM (Array Syntax) :=
forallBoundedTelescope indVal.type indVal.numParams fun xs _ => do
let mut binders := #[]