Skip to content

Commit 1ced8f6

Browse files
committed
Add the let* monadic notation
Inspired by the notation introduced by OCaml 4.08, we propose to introduce a new notation following the same principle. let* x := p in q is strictly equivalent to x <- p;; q The former can be made available by importing the newly introduced [MonadLetNotation]. Loading this module does not provide the arrow-based notation, which can still be made available by importing the [MonadNotation] module as before.
1 parent ae627bc commit 1ced8f6

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

examples/Notations.v

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Require Import ExtLib.Structures.Monad.
2+
Generalizable All Variables.
3+
4+
Module NotationExample.
5+
6+
Import MonadNotation.
7+
Open Scope monad_scope.
8+
9+
Fixpoint repeatM `{Monad M} (n : nat) `(x : A) (p : A -> M A) : M unit :=
10+
match n with
11+
| O => ret tt
12+
| S n => y <- p x;;
13+
repeatM n y p
14+
end.
15+
16+
End NotationExample.
17+
18+
Module LetNotationExample.
19+
20+
Import MonadLetNotation.
21+
Open Scope monad_scope.
22+
23+
Fixpoint repeatM `{Monad M} (n : nat) `(x : A) (p : A -> M A) : M unit :=
24+
match n with
25+
| O => ret tt
26+
| S n => let* y := p x in
27+
repeatM n y p
28+
end.
29+
30+
End LetNotationExample.

examples/_CoqProject

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ MonadReasoning.v
77
Printing.v
88
UsingSets.v
99
WithDemo.v
10+
Notations.v

theories/Structures/Monad.v

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,29 +49,47 @@ Section monadic.
4949

5050
End monadic.
5151

52-
Module MonadNotation.
52+
Module MonadBaseNotation.
5353

5454
Delimit Scope monad_scope with monad.
5555

5656
Notation "c >>= f" := (@bind _ _ _ _ c f) (at level 58, left associativity) : monad_scope.
5757
Notation "f =<< c" := (@bind _ _ _ _ c f) (at level 61, right associativity) : monad_scope.
5858
Notation "f >=> g" := (@mcompose _ _ _ _ _ f g) (at level 61, right associativity) : monad_scope.
5959

60+
Notation "e1 ;; e2" := (@bind _ _ _ _ e1%monad (fun _ => e2%monad))%monad
61+
(at level 61, right associativity) : monad_scope.
62+
63+
End MonadBaseNotation.
64+
65+
Module MonadNotation.
66+
67+
Export MonadBaseNotation.
68+
6069
Notation "x <- c1 ;; c2" := (@bind _ _ _ _ c1 (fun x => c2))
6170
(at level 61, c1 at next level, right associativity) : monad_scope.
6271

6372
Notation "` x : t <- c1 ;; c2" := (@bind _ _ _ _ c1 (fun x : t => c2))
6473
(at level 61, t at next level, c1 at next level, x ident, right associativity) : monad_scope.
6574

66-
Notation "e1 ;; e2" := (_ <- e1%monad ;; e2%monad)%monad
67-
(at level 61, right associativity) : monad_scope.
68-
6975
Notation "' pat <- c1 ;; c2" :=
7076
(@bind _ _ _ _ c1 (fun x => match x with pat => c2 end))
7177
(at level 61, pat pattern, c1 at next level, right associativity) : monad_scope.
7278

7379
End MonadNotation.
7480

81+
Module MonadLetNotation.
82+
83+
Export MonadBaseNotation.
84+
85+
Notation "'let*' x ':=' c1 'in' c2" := (@bind _ _ _ _ c1 (fun x => c2))
86+
(at level 61, c1 at next level, right associativity) : monad_scope.
87+
88+
Notation "'`let*' x ':' t ':=' c1 'in' c2" := (@bind _ _ _ _ c1 (fun x : t => c2))
89+
(at level 61, t at next level, c1 at next level, x ident, right associativity) : monad_scope.
90+
91+
End MonadLetNotation.
92+
7593
Section Instances.
7694

7795
Universe d c.

0 commit comments

Comments
 (0)