Note: some code is already defined in the Draft pull-request #58 and can be re-used.
Define a bare monad like:
Module M.
Inductive t (A : Set) : Set :=
| Pure : A -> t A
| Bind B : t B -> (B -> t A) -> t A.
Arguments Pure {_}.
Arguments Bind {_ _}.
End M.
with a notation let*
for M.Bind
.
Use this monad to make a monadic translation of the code. This will necessitate adding an M
to all the return types of functions:
Definition f (s : string) : bool :=
...
becomes:
Definition f (s : string) : M bool :=
...
and this will necessitate to name all the intermediate values for the monadic translation:
becomes:
let* ๐ฃ_1 := g(| b |) in
f(| a, ๐ฃ_1 |)
for example. Note that we use a Unicode character ๐ฃ
to limit name collisions (unless if this character is also used in Rust, but that should be rare).