Zulip Chat Archive
Stream: general
Topic: recursing over nd homogenous array
Frederick Pu (Dec 25 2024 at 00:35):
Hi, I'm trying to make a helper function for converting an nd homogenous list to a string, but get the following error, does anyone have any tips on how to fix this?
-- n nested homogenous Array
inductive NArray (α : Type u) : Nat → Type u where
| nil (n : Nat) : NArray α n
| cons₁ (a : α) (l : NArray α 1) : NArray α 1
| cons₂ {n : Nat} (a : NArray α n) (l : NArray α (n+1)) : NArray α (n + 1)
def aux {α : Type} [ToString α] {n : Nat} : NArray α n → String
| NArray.nil n => ""
| NArray.cons₁ a (NArray.nil 1) => toString a
| NArray.cons₁ a l => toString a ++ ", " ++ aux l
| NArray.cons₂ a (NArray.nil (n + 1))=> "[" ++ aux a ++ "]"
| NArray.cons₂ a l => "[" ++ aux a ++ "]" ++ ", " ++ aux l
/-
application type mismatch
a.cons₂ (NArray.nil (n + 1))
argument
NArray.nil (n + 1)
has type
NArray ?m.1350 (n + 1) : Type ?u.1349
but is expected to have type
NArray α (?m.1348 + 1) : Type
-/
Miyahara Kō (Dec 25 2024 at 00:52):
Short answer: Try this
def aux {α : Type} [ToString α] {n : Nat} : NArray α n → String
| NArray.nil n => ""
| NArray.cons₁ a (NArray.nil 1) => toString a
| NArray.cons₁ a l => toString a ++ ", " ++ aux l
| NArray.cons₂ (n := n) a (NArray.nil .(n + 1))=> "[" ++ aux a ++ "]"
| NArray.cons₂ a l => "[" ++ aux a ++ "]" ++ ", " ++ aux l
Frederick Pu (Dec 25 2024 at 00:59):
what is the (n := n) notation ?
Kevin Buzzard (Dec 25 2024 at 01:00):
https://lean-lang.org/lean4/doc/lean3changes.html#function-applications
Miyahara Kō (Dec 25 2024 at 01:00):
Long answer:
This is because Lean can't infer n
as an argument of NArray.cons₂
, which is implicit argument.
So, we should tell Lean that n
is an implicit argument of NArray.cons₂
, writing (n := n)
.
(continue)
Frederick Pu (Dec 25 2024 at 01:01):
ohhh
so this also works then:
def aux {α : Type} [ToString α] {n : Nat} : NArray α n → String
| NArray.nil n => ""
| NArray.cons₁ a (NArray.nil 1) => toString a
| NArray.cons₁ a l => toString a ++ ", " ++ aux l
| NArray.cons₂ a (NArray.nil (_ + 1))=> "[" ++ aux a ++ "]"
| NArray.cons₂ a l => "[" ++ aux a ++ "]" ++ ", " ++ aux l
Frederick Pu (Dec 25 2024 at 01:01):
or this:
def aux {α : Type} [ToString α] {n : Nat} : NArray α n → String
| NArray.nil n => ""
| NArray.cons₁ a (NArray.nil 1) => toString a
| NArray.cons₁ a l => toString a ++ ", " ++ aux l
| NArray.cons₂ a (NArray.nil _)=> "[" ++ aux a ++ "]"
| NArray.cons₂ a l => "[" ++ aux a ++ "]" ++ ", " ++ aux l
Miyahara Kō (Dec 25 2024 at 01:05):
(continued from my last post)
However, Lean gives an error that the same argument can't be used twice now.
So, we mark n + 1
by .(n + 1)
, which tells Lean that no new arguments are here.
Frederick Pu (Dec 25 2024 at 01:06):
im still kinda confused by what that means tho
Miyahara Kō (Dec 25 2024 at 01:10):
I was also confused at first, but after writing complex pattern matching, I naturally understood it, so it is no problem even if I don't understand it very well now:+1:
Frederick Pu (Dec 25 2024 at 01:13):
im sure ill deal with similar stuff in the future lol
Miyahara Kō (Dec 25 2024 at 01:31):
Let's look at a more obvious example.
Let's define an empty list of natural number.
List.nil
is often used in the form of []
.
def myList := List.nil
This causes error because Lean can't infer whose type is this list, in other word, Lean doesn't know what is α
:
inductive List (α : Type u) where
| nil : List α
| cons (head : α) (tail : List α) : List α
So we tell Lean that α
is Nat
, writing (α := Nat)
.
def myList := List.nil (α := Nat)
Frederick Pu (Dec 25 2024 at 13:54):
so the := allows you to specify a specific implicit parameter without having to specify all of them?
Ruben Van de Velde (Dec 25 2024 at 13:54):
yes
Frederick Pu (Dec 25 2024 at 13:55):
so in this case : | NArray.cons₂ (n := n) a (NArray.nil .(n + 1))
, the first n := n
specifies the implicit parameter for the cons_2 and the .(n + 1) makes it so that implicit parameter is also used for the Narray.nil?
Frederick Pu (Dec 25 2024 at 13:56):
ig my other question would be where the n on the right hand side of n := n comes from, is that the one from the top of function declaration {n : Nat}
?
Last updated: May 02 2025 at 03:31 UTC