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
barnot the same as the type offoo iwhenbaris defined to befoo i? - I am not sure what
#evalis complaining about in the final line. Is it complaining thatiis 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 iis 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