Zulip Chat Archive
Stream: metaprogramming / tactics
Topic: using `Lean.TSyntax.replaceM` to replace a hole in a type
Chris Henson (Jan 30 2025 at 16:53):
I am trying to write an elaborator filltype
to replace a hole (meant for a type variable) with a given type. E.g. filltype Int (List ?X)
to List Int
. For a single type, something like this seems to work, but the last result here is unexpected:
import Lean.Elab.Command
open Lean Elab Tactic Command
syntax (name := filltype) "filltype" : term
elab_rules : term
| `(filltype $tyvar:term $expr:term) => do
let pattern ← expr.raw.replaceM fun stx =>
if stx.isOfKind ``Parser.Term.syntheticHole then
pure tyvar
else
pure stx
Term.elabType pattern
-- these two are as expected
#check filltype Int ?X -- Int : Type
#check filltype Int Nat -- Nat : Type
-- but this seems to have no effect
#check filltype Int (List ?X) -- List ?X : Type u_1
Chris Henson (Jan 30 2025 at 17:07):
In case it is relevant, the fuller scope of what I'd like the elaborator to do is take some type with holes, e.g. List (?X x ?Y)
, and elaborate to a command that looks something like
instance {X Y : Type} [A X] [A Y] : B (List (X x Y))
where A
and B
are some existing typeclasses.
Kyle Miller (Jan 30 2025 at 17:15):
For replaceM, if you return non-none
, then it accepts that as the replacement and it does not recurse.
Try doing pure none
in the else
clause instead
Chris Henson (Jan 30 2025 at 17:23):
That worked, thanks!
Last updated: May 02 2025 at 03:31 UTC