In the standard library, we should use explicit universe variables for universe polymorphic definitions. Users that want to declare universe polymorphic definitions but do not want to provide universe level parameters should use Type _ or Type*
30 lines
769 B
Text
30 lines
769 B
Text
open bool nat
|
|
open function
|
|
|
|
inductive univ
|
|
| ubool : univ
|
|
| unat : univ
|
|
| uarrow : univ → univ → univ
|
|
|
|
open univ
|
|
|
|
attribute [reducible]
|
|
definition interp : univ → Type
|
|
| ubool := bool
|
|
| unat := nat
|
|
| (uarrow fr to) := interp fr → interp to
|
|
|
|
definition foo : Π (u : univ) (el : interp u), interp u
|
|
| ubool tt := ff
|
|
| ubool ff := tt
|
|
| unat n := succ n
|
|
| (uarrow fr to) f := λ x : interp fr, f (foo fr x)
|
|
|
|
definition is_even : nat → bool
|
|
| zero := tt
|
|
| (succ n) := bnot (is_even n)
|
|
|
|
example : foo unat (10:nat) = 11 := rfl
|
|
example : foo ubool tt = ff := rfl
|
|
example : foo (uarrow unat ubool) (λ x : nat, is_even x) 3 = tt := rfl
|
|
example : foo (uarrow unat ubool) (λ x : nat, is_even x) 4 = ff := rfl
|