Zulip Chat Archive
Stream: lean4
Topic: Implicit type argument impossible to access?
Niklas Halonen (Apr 02 2024 at 14:43):
Hi all,
While defining Church booleans, I ran into an issue where it doesn't seem possible to specify a non-uniform implicit type argument.
Here's my code:
universe u
def Cbool := {T : Sort u} → T → T → T
#check Cbool -- Cbool.{u} : Sort (imax (u + 1) u)
#check @Cbool Nat -- error: function expected
#check Cbool (T := Nat) -- error: invalid argument name 'T'
-- How to unify T✝ with U?
def tt {U : Sort u} : Cbool := fun (x _y : U) => x
Is there a way to explicitly specify the type T
for Cbool
to be U
?
Edward van de Meent (Apr 02 2024 at 15:08):
if you don't mind changing the definition a tad, this works:
def Cbool {T : Sort u} : Sort _ := T → T → T
Edward van de Meent (Apr 02 2024 at 15:09):
or, at least, i think it does?
Edward van de Meent (Apr 02 2024 at 15:09):
i might not completely understand your intention here
Edward van de Meent (Apr 02 2024 at 15:11):
reading your message again, i believe it might also be the case that you want (T → T) → T
rather than T → T → T
?
Niklas Halonen (Apr 02 2024 at 16:56):
Edward van de Meent said:
if you don't mind changing the definition a tad, this works:
def Cbool {T : Sort u} : Sort _ := T → T → T
Thanks for responding; unfortunately that makes handling the type parameter T
very inconvenient and ugly:
def Cbool := {T : Sort u} → T → T → T
def ff : Cbool := fun _x y => y
-- This works and is pretty
def Cbool.and : Cbool → Cbool → Cbool := fun b1 b2 => b1 b2 ff
-- Method call (almost) works
#eval Cbool.to_bool <| ff.and ff -- false
#eval (ff.and ff).to_bool -- error: invalid field notation
-- However, moving the type parameter to be uniform
def Cbool' {T : Sort u} := T → T → T
def ff' : @Cbool' T := fun (_x y : T) => y
-- This doesn't work
def Cbool'.and : Cbool' → Cbool' → Cbool' := fun b1 b2 => b1 b2 ff'
-- This works but is too ugly
def Cbool'.and' : @Cbool' (@Cbool' T) → (@Cbool' T) → (@Cbool' T) := fun b1 b2 => b1 b2 ff'
-- Also methods don't work for some reason
#eval Cbool'.to_bool <| ff'.and' ff'
My current solution is to define the following Cbool
hierarchy, which allows me to refer to the underlying type when necessary:
def CboolTTT {T : Sort u} {_t : T} {_t' : T} := T
def CboolTT {T : Sort u} {t : T} := (t' : T) → @CboolTTT T t t'
def CboolT {T : Sort u} := (t : T) → @CboolTT T t
def Cbool := {T : Sort u} → @CboolT T
-- Example for accessing the inner T type
def tt : @CboolT T := fun (x _y : T) => x
If you have better suggestions, please let me know!
Kyle Miller (Apr 02 2024 at 17:10):
There's a difference between
def Cbool := {T : Sort u} → T → T → T
and
def Cbool := fun {T : Sort u} => T → T → T
It seems like you're wanting to work with the first as if it were the second. Or maybe you want a feature that can specialize a pi type?
Niklas Halonen (May 01 2024 at 08:33):
Hmm, I think I get it. In the end I went with an explicit parameter def Cbool := (T : Type u) → T → T → T
which made everything much easier :smiley:
Last updated: May 02 2025 at 03:31 UTC