Consider a type ψ which is an inductive datatype using a single constructor mk (a : α) (b : β) : ψ.
Lean will automatically make two projection functions a : ψ → α, b : ψ → β.
Lean tags these declarations as projections.
This helps the simplifier / rewriter not have to expand projectors.
Eg a (mk x y) will automatically reduce to x.
If you extend a structure, all of the projections on the parent will also be created for the child.
Projections are also treated differently in the VM for efficiency.
Note that projections have nothing to do with the dot mylist.map syntax.
You can find out if a declaration is a projection using environment.is_projection which returns projection_info.
Data for a projection declaration:
cnameis the name of the constructor associated with the projection.nparamsis the number of constructor parameters. Egand.introhas two type parameters.idxis the parameter being projected by this projection.is_classis tt iff this is a typeclass projection.
Examples: #
and.rightis a projection with{cname := `and.intro, nparams := 2, idx := 1, is_class := ff}ordered_ring.negis a projection with{cname := `ordered_ring.mk, nparams := 1, idx := 5, is_class := tt}.
Instances for environment.projection_info
- environment.projection_info.has_sizeof_inst
- environment.projection_info.inhabited
- implicit : environment.implicit_infer_kind
- relaxed_implicit : environment.implicit_infer_kind
- none : environment.implicit_infer_kind
A marking on the binders of structures and inductives indicating how this constructor should mark its parameters.
inductive foo
| one {} : foo -> foo -- relaxed_implicit
| two ( ) : foo -> foo -- explicit
| two [] : foo -> foo -- implicit
| three : foo -> foo -- relaxed implicit (default)
Instances for environment.implicit_infer_kind
- environment.implicit_infer_kind.has_sizeof_inst
- environment.implicit_infer_kind.inhabited