Theory Maybe

(*<*)
(*
 * The Maybe monad.
 * (C)opyright 2009-2011, Peter Gammie, peteg42 at gmail.com.
 * License: BSD
 *)

theory Maybe
imports HOLCF
begin
(*>*)

section‹The 'a Maybe› Monad›

text‹This section defines the monadic machinery for the 'a
Maybe› type. @{term "return"} is @{term "Just"}.›

domain 'a Maybe = Nothing | Just (lazy "'a")

definition
  mfail :: "'a Maybe"
where
  "mfail  Nothing"

definition
  mcatch :: "'a Maybe  'a Maybe  'a Maybe"
where
  "mcatch  Λ body handler. case body of Nothing  handler | Justx  Justx"

lemma mcatch_strict[simp]: "mcatch = "
  by (rule cfun_eqI, simp add: mcatch_def)

definition
  mbind :: "'a Maybe  ('a  'b Maybe)  'b Maybe" where
  "mbind  Λ f g. (case f of Nothing  Nothing | Justf'  gf')"

abbreviation
  mbind_syn :: "'a Maybe  ('a  'b Maybe)  'b Maybe" (infixl >>=M 55) where
  "f >>=M g  mbindfg"

lemma mbind_strict1[simp]: " >>=M g = " by (simp add: mbind_def)

text‹The standard monad laws.›

lemma leftID[simp]: "Justa >>=M f = fa" by (simp add: mbind_def)
lemma rightID[simp]: "m >>=M Just = m" by (cases m, simp_all add: mbind_def)

lemma assoc[simp]: "(m >>=M f) >>=M g = m >>=M (Λ x. fx >>=M g)"
  by (cases m, simp_all add: mbind_def)

text‹Reduction for the Maybe monad.›

lemma nothing_bind[simp]: "Nothing >>=M f = Nothing" by (simp add: mbind_def)
lemma just_bind[simp]: "Justx >>=M f = fx" by (simp add: mbind_def)

definition
  mliftM2 :: "('a  'b  'c)  'a Maybe  'b Maybe  'c Maybe" where
  "mliftM2 f  Λ x y. x >>=M (Λ x'. y >>=M (Λ y'. Just(fx'y')))"

lemma mliftM2_Nothing1[simp]: "mliftM2 fNothingy = Nothing" by (simp add: mliftM2_def)
lemma mliftM2_Nothing2[simp]: "mliftM2 f(Justx)Nothing = Nothing" by (simp add: mliftM2_def)
lemma mliftM2_op[simp]: "mliftM2 f(Justx)(Justy) = Just(fxy)" by (simp add: mliftM2_def)

lemma mliftM2_strict1[simp]: "mliftM2 f = " by (rule cfun_eqI)+ (simp add: mliftM2_def)
lemma mliftM2_strict2[simp]: "mliftM2 f(Justx) = " by (simp add: mliftM2_def)

end