Zulip Chat Archive
Stream: new members
Topic: Puzzled by an example on types
Kevin Cheung (May 30 2024 at 14:04):
I have the following:
import Mathlib.Data.Finset.Basic
def foo {m n : ℕ} (_ : (Fin n × Fin m)) := m * n
variable (i : Fin 5 × Fin 6)
#check (foo i) -- for i : ℕ
def bar := foo i
#check bar -- bar (i : Fin 5 × Fin 6) : ℕ -- Why is this different from #check (foo i)?
#reduce bar -- fun i ↦ 30
#reduce (foo i) -- 30
#eval (foo i) -- (kernel) declaration has free variables '_eval'
- Why is the type of
bar
not the same as the type offoo i
whenbar
is defined to befoo i
? - I am not sure what
#eval
is complaining about in the final line. Is it complaining thati
is a free variable?
Lua Viana Reis (May 30 2024 at 14:29):
This is because variable (i : Fin 5 × Fin 6)
turns i
into a parameter for all the following definitions whenever they mention i
. This is why the type of bar
is different, it still requires a parameter with the same type as i
.
Lua Viana Reis (May 30 2024 at 14:34):
And I believe eval
is complaining that i
is not defined (it is a free variable), even though you don' t need its definition and its type is fixed, it is still an undefined parameter.
Lua Viana Reis (May 30 2024 at 14:36):
Change this line to def i := ((0,0) : Fin 5 × Fin 6)
and it all works
Kevin Cheung (May 30 2024 at 14:37):
So, in the code above def bar := foo i
is syntactic sugar for def bar (i : Fin 5 × Fin) := foo i
?
What I don't understand here is why #check (foo i)
doesn't give the same type as bar
.
Lua Viana Reis (May 30 2024 at 14:41):
Kevin Cheung said:
So, in the code above
def bar := foo i
is syntactic sugar fordef bar (i : Fin 5 × Fin) := foo i
?
Exactly. And this is exactly why it doesn't give the same type.
Kevin Cheung (May 30 2024 at 14:44):
So, is it impossible to define something that is exactly what foo i
is in #check (foo i)
?
Lua Viana Reis (May 30 2024 at 14:50):
I don't believe this is possible without some hackery, because it would mean that the free variable i
is leaking outside the section/module. Imagine if you were to reference this definition from other file, what would i
be?
In a more extreme case, you could have (i : False)
, and if it wasn't turned into a parameter for bar
, then bar
used outside would be silently assuming something false from a different context.
Kevin Cheung (May 30 2024 at 16:34):
I see. So #check foo i
basically reduces foo i
first before showing its type?
Last updated: May 02 2025 at 03:31 UTC