Skip to content

Commit c50f04a

Browse files
authored
feat: add delaborators for <|>, <*>, >>, <*, and *> (leanprover#5854)
Closes leanprover#5668
1 parent 8b5443e commit c50f04a

File tree

4 files changed

+70
-7
lines changed

4 files changed

+70
-7
lines changed

src/Init/Notation.lean

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -341,16 +341,19 @@ macro_rules | `($x == $y) => `(binrel_no_prop% BEq.beq $x $y)
341341
notation:50 a:50 " ∉ " b:50 => ¬ (a ∈ b)
342342

343343
@[inherit_doc] infixr:67 " :: " => List.cons
344-
@[inherit_doc HOrElse.hOrElse] syntax:20 term:21 " <|> " term:20 : term
345-
@[inherit_doc HAndThen.hAndThen] syntax:60 term:61 " >> " term:60 : term
346-
@[inherit_doc] infixl:55 " >>= " => Bind.bind
347-
@[inherit_doc] notation:60 a:60 " <*> " b:61 => Seq.seq a fun _ : Unit => b
348-
@[inherit_doc] notation:60 a:60 " <* " b:61 => SeqLeft.seqLeft a fun _ : Unit => b
349-
@[inherit_doc] notation:60 a:60 " *> " b:61 => SeqRight.seqRight a fun _ : Unit => b
350344
@[inherit_doc] infixr:100 " <$> " => Functor.map
345+
@[inherit_doc] infixl:55 " >>= " => Bind.bind
346+
@[inherit_doc HOrElse.hOrElse] syntax:20 term:21 " <|> " term:20 : term
347+
@[inherit_doc HAndThen.hAndThen] syntax:60 term:61 " >> " term:60 : term
348+
@[inherit_doc Seq.seq] syntax:60 term:60 " <*> " term:61 : term
349+
@[inherit_doc SeqLeft.seqLeft] syntax:60 term:60 " <* " term:61 : term
350+
@[inherit_doc SeqRight.seqRight] syntax:60 term:60 " *> " term:61 : term
351351

352352
macro_rules | `($x <|> $y) => `(binop_lazy% HOrElse.hOrElse $x $y)
353353
macro_rules | `($x >> $y) => `(binop_lazy% HAndThen.hAndThen $x $y)
354+
macro_rules | `($x <*> $y) => `(Seq.seq $x fun _ : Unit => $y)
355+
macro_rules | `($x <* $y) => `(SeqLeft.seqLeft $x fun _ : Unit => $y)
356+
macro_rules | `($x *> $y) => `(SeqRight.seqRight $x fun _ : Unit => $y)
354357

355358
namespace Lean
356359

src/Lean/PrettyPrinter/Delaborator/Builtins.lean

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,30 @@ def delabDo : Delab := whenNotPPOption getPPExplicit <| whenPPOption getPPNotati
12181218
let items ← elems.toArray.mapM (`(doSeqItem|$(·):doElem))
12191219
`(do $items:doSeqItem*)
12201220

1221+
/-- Delaborates a function application of the form `f ... x (fun _ : Unit => y)`. -/
1222+
def delabLazyBinop (arity : Nat) (k : Term → Term → DelabM Term) : DelabM Term :=
1223+
whenNotPPOption getPPExplicit <| whenPPOption getPPNotation <| withOverApp arity do
1224+
let y ← withAppArg do
1225+
let b := (← getExpr).beta #[mkConst ``Unit.unit]
1226+
withTheReader SubExpr (fun s => {s with pos := s.pos.pushBindingBody, expr := b}) delab
1227+
let x ← withAppFn <| withAppArg delab
1228+
k x y
1229+
1230+
@[builtin_delab app.HOrElse.hOrElse]
1231+
def delabHOrElse : Delab := delabLazyBinop 6 (fun x y => `($x <|> $y))
1232+
1233+
@[builtin_delab app.HAndThen.hAndThen]
1234+
def delabHAndThen : Delab := delabLazyBinop 6 (fun x y => `($x >> $y))
1235+
1236+
@[builtin_delab app.Seq.seq]
1237+
def delabSeq : Delab := delabLazyBinop 6 (fun x y => `($x <*> $y))
1238+
1239+
@[builtin_delab app.SeqLeft.seqLeft]
1240+
def delabSeqLeft : Delab := delabLazyBinop 6 (fun x y => `($x <* $y))
1241+
1242+
@[builtin_delab app.SeqRight.seqRight]
1243+
def delabSeqRight : Delab := delabLazyBinop 6 (fun x y => `($x *> $y))
1244+
12211245
@[builtin_delab app.Lean.Name.str,
12221246
builtin_delab app.Lean.Name.mkStr1, builtin_delab app.Lean.Name.mkStr2, builtin_delab app.Lean.Name.mkStr3, builtin_delab app.Lean.Name.mkStr4,
12231247
builtin_delab app.Lean.Name.mkStr5, builtin_delab app.Lean.Name.mkStr6, builtin_delab app.Lean.Name.mkStr7, builtin_delab app.Lean.Name.mkStr8]

tests/lean/eagerCoeExpansion.lean.expected.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ fun (a : Nat) =>
1818
(@bne.{0} Nat (@instBEqOfDecidableEq.{0} Nat instDecidableEqNat) a (@OfNat.ofNat.{0} Nat 2 (instOfNatNat 2)))
1919
Bool.true)
2020
def s : Option Nat :=
21-
HOrElse.hOrElse (myFun.f 3) fun x => myFun.f 4
21+
myFun.f 3 <|> myFun.f 4

tests/lean/run/5668.lean

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import Lean
2+
/-!
3+
# Pretty printing of `<|>`, `<*>`, `>>`, `<*`, and `*>`
4+
5+
https://github.com/leanprover/lean4/issues/5668
6+
-/
7+
8+
/-- info: none <|> some false : Option Bool -/
9+
#guard_msgs in #check none <|> some false
10+
11+
variable [Monad m] (a : m α) (b : m β) (f : m (α → β))
12+
13+
/-- info: f <*> a : m β -/
14+
#guard_msgs in #check f <*> a
15+
16+
/-- info: a <* b : m α -/
17+
#guard_msgs in #check a <* b
18+
19+
/-- info: a *> b : m β -/
20+
#guard_msgs in #check a *> b
21+
22+
/-- info: Lean.Parser.ident >> Lean.Parser.symbol "hi" : Lean.Parser.Parser -/
23+
#guard_msgs in #check Lean.Parser.ident >> "hi"
24+
25+
26+
/-!
27+
Dependent, substitutes in `()`.
28+
-/
29+
/-- info: some true <|> some (() == ()) : Option Bool -/
30+
#guard_msgs in #check HOrElse.hOrElse (some true) (fun h => some <| h == ())
31+
32+
/-!
33+
Not a lambda, applies `()`.
34+
-/
35+
/-- info: some true <|> Function.const Unit (some true) () : Option Bool -/
36+
#guard_msgs in #check HOrElse.hOrElse (some true) (Function.const _ (some true))

0 commit comments

Comments
 (0)