cpsa-4.4.6: coq/Monad.v
(* Monadic Operations
Copyright (c) 2021 The MITRE Corporation
This program is free software: you can redistribute it and/or
modify it under the terms of the BSD License as published by the
University of California. *)
(** * Monadic Operations on Option Types *)
From Stdlib Require Import List.
Import List.ListNotations.
Open Scope list_scope.
(** printing <- #←# *)
(** Haskell do-like notation for option types *)
Notation "x <- M ;; N" := (match M with None => None | Some x => N end)
(at level 30, right associativity).
Lemma do_some:
forall A B (f: option A) (g: A -> option B) b,
x <- f;; g x = Some b ->
exists a, f = Some a /\ g a = Some b.
Proof.
intros.
destruct f as [x|].
- exists x; auto.
- inversion H.
Qed.
(** Monadic map *)
Fixpoint map_m {A B} (f: A -> option B) (l: list A): option (list B) :=
match l with
| [] => Some []
| x :: xs =>
y <- f x;;
ys <- map_m f xs;;
Some (y :: ys)
end.
Lemma map_m_nil:
forall A B (f: A -> option B) x xs,
map_m f (x :: xs) <> Some [].
Proof.
intros.
intro.
simpl in H.
apply do_some in H.
destruct H as [y H].
destruct H as [H G].
apply do_some in G.
destruct G as [ys G].
destruct G as [G F].
inversion F.
Qed.
Lemma map_m_pair:
forall A B (f: A -> option B) x xs y ys,
map_m f (x :: xs) = Some (y :: ys) ->
f x = Some y /\ map_m f xs = Some ys.
Proof.
intros.
simpl in H.
apply do_some in H.
destruct H as [z H].
destruct H as [H G].
apply do_some in G.
destruct G as [zs G].
destruct G as [G F].
inversion F; subst; auto.
Qed.
(** Monadic fold *)
Fixpoint fold_m {A B} (f: A -> B -> option A)
(a: A) (l: list B): option A :=
match l with
| [] => Some a
| x :: xs =>
b <- f a x;;
fold_m f b xs
end.