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:
cname
is the name of the constructor associated with the projection.nparams
is the number of constructor parameters. Egand.intro
has two type parameters.idx
is the parameter being projected by this projection.is_class
is tt iff this is a typeclass projection.
Examples: #
and.right
is a projection with{cname := `and.intro, nparams := 2, idx := 1, is_class := ff}
ordered_ring.neg
is a projection with{cname := `ordered_ring.mk, nparams := 1, idx := 5, is_class := tt}
.
- 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)