ListP tund ListI tsind isomorph: Sie haben genau die gleichen Konstruktoren.
<prompt>Coq < 12 || 0 < </prompt>Check (NilP, NilI).
(NilP, NilI)
: (forall t : Type, ListP t) *
(forall t : Type, ListI t)
<prompt>Coq < 13 || 0 < </prompt>Check (ConsP, ConsI).
(ConsP, ConsI)
: (forall t : Type, t -> ListP t -> ListP t) *
(forall t : Type, t -> ListI t -> ListI t)
Coq erzeugt jedoch unterschiedliche Induktionsprinzipien.
<prompt>Coq < 14 || 0 < </prompt>Check (ListP_ind, ListI_ind).
(ListP_ind, ListI_ind)
: (forall (t : Type) (P : ListP t -> Prop),
P (NilP t) ->
(forall (t0 : t) (l : ListP t), P l -> P (ConsP t t0 l)) ->
forall l : ListP t, P l) *
(forall P : forall T : Type, ListI T -> Prop,
(forall t : Type, P t (NilI t)) ->
(forall (t : Type) (t0 : t) (l : ListI t),
P t l -> P t (ConsI t t0 l)) ->
forall (T : Type) (l : ListI T), P T l)
Das Induktionsprinzip von ListIerfordert, dass die Eigenschaft im Elementtyp ( P : forall T, ListI T -> Prop) parametrisch ist, während das Induktionsprinzip von ListPbei jedem Typ t( P : ListP t -> Prop) instanziiert werden kann . Dies ist eine Schwäche von Coqs Front-End, da ungleichmäßige rekursive Typen nicht klug sind. Sie können dasselbe Induktionsprinzip manuell definieren (der Typechecker akzeptiert es, was nicht überraschend ist, da es ListP_inddurch den offensichtlichen Isomorphismus zwischen ListPund transformiert wird ListI).
Das parametrische Formular ListPist einfacher und sofort einsatzbereit. Das ListIFormular kann auf eine ungleichmäßige Rekursion verallgemeinert werden, bei der die Parameter in den rekursiven Aufrufen nicht das Original sind. Ein Beispiel finden Sie unter Polymorphismus und induktive Datentypen .