(f a) is ill-typed where f:(x:A)B and a:A'. If there is a
coercion path between A' and A, (f a) is transformed into
(f a') where a' is the result of the application of this
coercion path to a.
We first give an example of coercion between atomic inductive types
Coq < Definition bool_in_nat := [b:bool]if b then O else (S O).
bool_in_nat is defined
Coq < Coercion bool_in_nat : bool >-> nat.
bool_in_nat is now a coercion
Coq < Check O=true.
O=true
: Prop
Coq < Set Printing Coercions.
Coq < Check O=true.
O=(bool_in_nat true)
: Prop
Warning: ``Check true=O.
'' fails. This is ``normal'' behaviour of
coercions. To validate true=O
, the coercion is searched from
nat
to bool
. There is no one.
We give an example of coercion between classes with parameters.
Coq < Parameters C:nat->Set; D:nat->bool->Set; E:bool->Set.
C is assumed
D is assumed
E is assumed
Coq < Parameter f : (n:nat)(C n) -> (D (S n) true).
f is assumed
Coq < Coercion f : C >-> D.
f is now a coercion
Coq < Parameter g : (n:nat)(b:bool)(D n b) -> (E b).
g is assumed
Coq < Coercion g : D >-> E.
g is now a coercion
Coq < Parameter c : (C O).
c is assumed
Coq < Parameter T : (E true) -> nat.
T is assumed
Coq < Check (T c).
(T c)
: nat
Coq < Set Printing Coercions.
Coq < Check (T c).
(T (g (S O) true (f O c)))
: nat
We give now an example using identity coercions.
Coq < Definition D' := [b:bool](D (S O) b).
D' is defined
Coq < Identity Coercion IdD'D : D' >-> D.
Coq < Print IdD'D.
IdD'D =
([b:bool; x:(D' b)]x)::((b:bool)(D' b)->(D (S O) b))
: (b:bool)(D' b)->(D (S O) b)
Coq < Parameter d' : (D' true).
d' is assumed
Coq < Check (T d').
(T d')
: nat
Coq < Set Printing Coercions.
Coq < Check (T d').
(T (g (S O) true d'))
: nat
In the case of functional arguments, we use the monotonic rule of
sub-typing. Approximatively, to coerce t:(x:A)B towards (x:A')B',
one have to coerce A' towards A and B towards B'. An example
is given below:
Coq < Parameters A,B:Set; h:A->B.
A is assumed
B is assumed
h is assumed
Coq < Coercion h : A >-> B.
h is now a coercion
Coq < Parameter U : (A -> (E true)) -> nat.
U is assumed
Coq < Parameter t : B -> (C O).
t is assumed
Coq < Check (U t).
(U [x:A](t x))
: nat
Coq < Set Printing Coercions.
Coq < Check (U t).
(U [x:A](g (S O) true (f O (t (h x)))))
: nat
Remark the changes in the result following the modification of the
previous example.
Coq < Parameter U' : ((C O) -> B) -> nat.
U' is assumed
Coq < Parameter t' : (E true) -> A.
t' is assumed
Coq < Check (U' t').
(U' [x:(C O)](t' x))
: nat
Coq < Set Printing Coercions.
Coq < Check (U' t').
(U' [x:(C O)](h (t' (g (S O) true (f O x)))))
: nat