Zulip Chat Archive
Stream: lean4
Topic: New syntax for Array access -- display syntax
Clément Blaudeau (Aug 04 2025 at 12:48):
Hi! As part of the Hax backend for Lean I'm trying to create a new syntax a[i]_? for array accesses that returns a custom Option type (that's why I'm not using a[i]? directly -- overriding GetElem? is not an option in my case).
I've copied the Lean definition of GetElem, and modified it to return an Result (a custom Option type with error cases)
class GetElemResult (coll : Type u) (idx : Type v) (elem : outParam (Type w)) where
getElemResult (xs : coll) (i : idx) : Result elem
export GetElemResult (getElemResult)
@[inherit_doc getElemResult]
syntax:max term noWs "[" withoutPosition(term) "]" noWs "_?": term
macro_rules | `($x[$i]_?) => `(getElemResult $x $i)
instance Nat.instGetElemResultArray {α} : GetElemResult (Array α) Nat α where
getElemResult xs i :=
if h: i < xs.size then pure (xs[i])
else .fail arrayOutOfBounds
It works, but internally, Lean does not keep the a[i]_?, but inlines them as calls to getElemResult, as can be seen by doing :
#check #[0,1,2,3][1]_? -- getElemResult #[0,1,2,3] 1 : Result Nat
#check #[0,1,2,3][1]? -- #[0,1,2,3][1]? : Option Nat
Am I missing a notation definition in addition to the macro ? I can't find any in the GetElem.lean file, unless perhaps this instance on Syntax ?
Thank you !
Aaron Liu (Aug 04 2025 at 13:37):
You need an unexpander or a delaborator
Aaron Liu (Aug 04 2025 at 13:39):
they're docs#unexpandGetElem and friends
Clément Blaudeau (Aug 04 2025 at 13:52):
Nice! Thank you! This works perfectly
@[app_unexpander getElemResult] meta def unexpandGetElemResult : Lean.PrettyPrinter.Unexpander
| `($_ $array $index) => `($array[$index]_?)
| _ => throw ()
Last updated: Dec 20 2025 at 21:32 UTC