Laws for Monads with Failure #
Definitions for monads that also have an Alternative instance while sharing the underlying
Applicative instance, and a class LawfulAlternative for types where the failure and orElse
operations behave in a natural way. More specifically they satisfy:
f <$> failure = failurefailure <*> x = failurex <|> failure = xfailure <|> y = yx <|> y <|> z = (x <|> y) <|> zf <$> (x <|> y) = (f <$> x <|> f <$> y)
Option/OptionT are the most basic examples, but transformers like StateT also preserve
the lawfulness of this on the underlying monad.
The law x *> failure = failure is true for monads like Option and List that don't
have any "side effects" to execution, but not for something like OptionT on some monads,
so we don't include this condition.
We also define a class LawfulAlternativeLift similar to LawfulMonadLift that states that
a lifting between monads preserves failure and orElse.
Tags #
monad, alternative, failure
AlternativeMonad m means that m has both a Monad and Alternative instance,
which both share the same underlying Applicative instance.
The main example is Option, but many monad transformers also preserve or add this structure.
Instances
LawfulAlternative m means that the failure operation on m behaves naturally
with respect to map, seq, and orElse operators.
- seq_assoc {α β γ : Type u_1} (x : m α) (g : m (α → β)) (h : m (β → γ)) : h <*> (g <*> x) = Function.comp <$> h <*> g <*> x
Mapping the result of a failure is still a failure
Sequencing a
failurecall results in failurefailureis a right identity fororElse.failureis a left identity fororElse.orElseis associative.mapcommutes withorElse. The stronger statement withbindgenerally isn't true
Instances
Type-class for monad lifts that preserve the Alternative operations.
Lifting preserves
failure.Lifting preserves
orElse.
Instances
Equations
- Option.instAlternativeMonad = { toAlternative := instAlternativeOption, toBind := instMonadOption.toBind }
Equations
- OptionT.instAlternativeMonadOfMonad m = { toAlternative := OptionT.instAlternative, toBind := OptionT.instMonad.toBind }
Equations
- StateT.instAlternativeMonad m = { toAlternative := StateT.instAlternative, toBind := StateT.instMonad.toBind }
Equations
- ReaderT.instAlternativeMonad = { toAlternative := ReaderT.instAlternativeOfMonad, toBind := ReaderT.instMonad.toBind }
Equations
- StateRefT'.instAlternativeMonad = { toAlternative := StateRefT'.instAlternativeOfMonad, toBind := StateRefT'.instMonad.toBind }