Skip to content

Instantly share code, notes, and snippets.

@VictorTaelin
Created June 24, 2025 10:46
Show Gist options
  • Save VictorTaelin/2d16cf9ccbf37f5b91e90c585ae260e1 to your computer and use it in GitHub Desktop.
Save VictorTaelin/2d16cf9ccbf37f5b91e90c585ae260e1 to your computer and use it in GitHub Desktop.

I'm thinking on how to add funext to a Type Theory in the spirit of that answer

my understanding is that OTT, as presented, introduces computation rules for a built-in identity / propositional equality type. for example, in OTT, we'd have something like:

Eq (A,B) (a0,b0) (a1,b1)

reduce to

(Eq A a0 a1 , Eq B b0 b1)

and the way that FunExt is implemented is by merely making:

Eq (∀(x:A).(B x)) f g

reduce to

∀x:A. Eq (B x) (f x) (g x)

or, in other words, the type of equality on functions is definitionaly equivalent to the type of a function that returns an equality on each point.

now, if I understand it right, you mention that this is inconvenient for some reasons and suggest, instead, to just let the user explicitly apply type eliminators to equalities of that type. for example, if:

x : Eq (A,B) (a0,b0) (a1,b1)

then,

fst x : Eq A a0 a1

that is, by letting the user project equalities as if they were values, we can emulate OTT without the inconveniences bought by the identity type computing to something else. I suspect that, in a similar way, you also allow one to inhabit the identity type by constructing an element of the type it equates. for example:

refl          : Eq (Bool,Bool) (True,False) (True,False)
(refl , refl) : Eq (Bool,Bool) (True,False) (True,False)

both would work. is that right?

if so, in that spirit, I suspect the proof of FunExt would go more or less like this:

funext
: ∀A: Set
  ∀B: A → Set
  ∀f: ∀(x:A). (B x)
  ∀g: ∀(x:A). (B x)
  ∀h: ∀(x:A). Eq (B x) (F x) (G x)
  Eq (∀(x:A).(B x)) f g
= λA. λB. λf. λg. λh.
  -- here, the goal is `Eq (∀(x:A).(B x)) f g`
  -- since this is an equality on a function type, we can introduce a lambda
  λx.
  -- here, the goal is `Eq (B x) (f x) (g x)`
  -- we can construct it by simply applying 'h' to 'x'
  (h x)
  -- this completes the proof

so basically all we need to implement FunExt is to let the compiler accept λx. as a way to introduce Eq (∀(x:A).(B x)) f g kind of

is this correct? am I on the right track?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment