ListP te ListI tsão isomórficos: eles têm exatamente os mesmos construtores.
<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)
No entanto, Coq gera diferentes princípios de indução.
<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)
O princípio de indução de ListIrequer que a propriedade seja paramétrica no tipo de elemento ( P : forall T, ListI T -> Prop) enquanto o princípio de indução de ListPpode ser instanciado em qualquer tipo t( P : ListP t -> Prop). Esta é uma fraqueza do front-end da Coq, na medida em que não é inteligente em relação a tipos recursivos não uniformes; você pode definir manualmente o mesmo princípio de indução (o typechecker o aceita, o que não surpreende, pois é ListP_indtransformado pelo óbvio isomorfismo entre ListPe ListI).
A forma paramétrica ListPé mais simples e fácil de usar pronta para uso. O ListIformulário pode generalizar para recursão não uniforme, onde os parâmetros nas chamadas recursivas não são os originais. Consulte Polimorfismo e tipos de dados indutivos para obter um exemplo.