Control.MonadPlus
- Package
- purescript-control
- Repository
- purescript/purescript-control
#MonadPlus Source
class MonadPlus :: (Type -> Type) -> Constraint
class (Monad m, Alternative m) <= MonadPlus m
The MonadPlus
type class has no members of its own; it just specifies
that the type has both Monad
and Alternative
instances.
Types which have MonadPlus
instances should also satisfy the following
law:
- Distributivity:
(x <|> y) >>= f == (x >>= f) <|> (y >>= f)
Instances
Re-exports from Control.Alt
#Alt Source
class Alt :: (Type -> Type) -> Constraint
class (Functor f) <= Alt f where
The Alt
type class identifies an associative operation on a type
constructor. It is similar to Semigroup
, except that it applies to
types of kind * -> *
, like Array
or List
, rather than concrete types
String
or Number
.
Alt
instances are required to satisfy the following laws:
- Associativity:
(x <|> y) <|> z == x <|> (y <|> z)
- Distributivity:
f <$> (x <|> y) == (f <$> x) <|> (f <$> y)
For example, the Array
([]
) type is an instance of Alt
, where
(<|>)
is defined to be concatenation.
A common use case is to select the first "valid" item, or, if all items are "invalid", the last "invalid" item.
For example:
import Control.Alt ((<|>))
import Data.Maybe (Maybe(..)
import Data.Either (Either(..))
Nothing <|> Just 1 <|> Just 2 == Just 1
Left "err" <|> Right 1 <|> Right 2 == Right 1
Left "err 1" <|> Left "err 2" <|> Left "err 3" == Left "err 3"
Members
alt :: forall a. f a -> f a -> f a
Instances
Re-exports from Control.Alternative
#Alternative Source
class Alternative :: (Type -> Type) -> Constraint
class (Applicative f, Plus f) <= Alternative f
The Alternative
type class has no members of its own; it just specifies
that the type constructor has both Applicative
and Plus
instances.
Types which have Alternative
instances should also satisfy the following
laws:
- Distributivity:
(f <|> g) <*> x == (f <*> x) <|> (g <*> x)
- Annihilation:
empty <*> f = empty
Instances
#guard Source
guard :: forall m. Alternative m => Boolean -> m Unit
Fail using Plus
if a condition does not hold, or
succeed using Applicative
if it does.
For example:
import Prelude
import Control.Alternative (guard)
import Data.Array ((..))
factors :: Int -> Array Int
factors n = do
a <- 1..n
b <- 1..n
guard $ a * b == n
pure a
Re-exports from Control.Applicative
#Applicative Source
class Applicative :: (Type -> Type) -> Constraint
class (Apply f) <= Applicative f where
The Applicative
type class extends the Apply
type class
with a pure
function, which can be used to create values of type f a
from values of type a
.
Where Apply
provides the ability to lift functions of two or
more arguments to functions whose arguments are wrapped using f
, and
Functor
provides the ability to lift functions of one
argument, pure
can be seen as the function which lifts functions of
zero arguments. That is, Applicative
functors support a lifting
operation for any number of function arguments.
Instances must satisfy the following laws in addition to the Apply
laws:
- Identity:
(pure identity) <*> v = v
- Composition:
pure (<<<) <*> f <*> g <*> h = f <*> (g <*> h)
- Homomorphism:
(pure f) <*> (pure x) = pure (f x)
- Interchange:
u <*> (pure y) = (pure (_ $ y)) <*> u
Members
pure :: forall a. a -> f a
Instances
#when Source
when :: forall m. Applicative m => Boolean -> m Unit -> m Unit
Perform an applicative action when a condition is true.
#unless Source
unless :: forall m. Applicative m => Boolean -> m Unit -> m Unit
Perform an applicative action unless a condition is true.
#liftA1 Source
liftA1 :: forall f a b. Applicative f => (a -> b) -> f a -> f b
liftA1
provides a default implementation of (<$>)
for any
Applicative
functor, without using (<$>)
as provided
by the Functor
-Applicative
superclass
relationship.
liftA1
can therefore be used to write Functor
instances
as follows:
instance functorF :: Functor F where
map = liftA1
Re-exports from Control.Apply
#Apply Source
class Apply :: (Type -> Type) -> Constraint
class (Functor f) <= Apply f where
The Apply
class provides the (<*>)
which is used to apply a function
to an argument under a type constructor.
Apply
can be used to lift functions of two or more arguments to work on
values wrapped with the type constructor f
. It might also be understood
in terms of the lift2
function:
lift2 :: forall f a b c. Apply f => (a -> b -> c) -> f a -> f b -> f c
lift2 f a b = f <$> a <*> b
(<*>)
is recovered from lift2
as lift2 ($)
. That is, (<*>)
lifts
the function application operator ($)
to arguments wrapped with the
type constructor f
.
Put differently...
foo =
functionTakingNArguments <$> computationProducingArg1
<*> computationProducingArg2
<*> ...
<*> computationProducingArgN
Instances must satisfy the following law in addition to the Functor
laws:
- Associative composition:
(<<<) <$> f <*> g <*> h = f <*> (g <*> h)
Formally, Apply
represents a strong lax semi-monoidal endofunctor.
Members
apply :: forall a b. f (a -> b) -> f a -> f b
Instances
Re-exports from Control.Bind
#Bind Source
class Bind :: (Type -> Type) -> Constraint
class (Apply m) <= Bind m where
The Bind
type class extends the Apply
type class with a
"bind" operation (>>=)
which composes computations in sequence, using
the return value of one computation to determine the next computation.
The >>=
operator can also be expressed using do
notation, as follows:
x >>= f = do y <- x
f y
where the function argument of f
is given the name y
.
Instances must satisfy the following laws in addition to the Apply
laws:
- Associativity:
(x >>= f) >>= g = x >>= (\k -> f k >>= g)
- Apply Superclass:
apply f x = f >>= \f’ -> map f’ x
Associativity tells us that we can regroup operations which use do
notation so that we can unambiguously write, for example:
do x <- m1
y <- m2 x
m3 x y
Members
bind :: forall a b. m a -> (a -> m b) -> m b
Instances
#(<=<) Source
Operator alias for Control.Bind.composeKleisliFlipped (right-associative / precedence 1)
Re-exports from Control.Monad
#Monad Source
class Monad :: (Type -> Type) -> Constraint
class (Applicative m, Bind m) <= Monad m
The Monad
type class combines the operations of the Bind
and
Applicative
type classes. Therefore, Monad
instances represent type
constructors which support sequential composition, and also lifting of
functions of arbitrary arity.
Instances must satisfy the following laws in addition to the
Applicative
and Bind
laws:
- Left Identity:
pure x >>= f = f x
- Right Identity:
x >>= pure = x
Instances
#liftM1 Source
liftM1 :: forall m a b. Monad m => (a -> b) -> m a -> m b
liftM1
provides a default implementation of (<$>)
for any
Monad
, without using (<$>)
as provided by the
Functor
-Monad
superclass relationship.
liftM1
can therefore be used to write Functor
instances
as follows:
instance functorF :: Functor F where
map = liftM1
Re-exports from Control.Plus
#Plus Source
class Plus :: (Type -> Type) -> Constraint
class (Alt f) <= Plus f where
The Plus
type class extends the Alt
type class with a value that
should be the left and right identity for (<|>)
.
It is similar to Monoid
, except that it applies to types of
kind * -> *
, like Array
or List
, rather than concrete types like
String
or Number
.
Plus
instances should satisfy the following laws:
- Left identity:
empty <|> x == x
- Right identity:
x <|> empty == x
- Annihilation:
f <$> empty == empty
Members
empty :: forall a. f a
Instances
Re-exports from Data.Functor
#Functor Source
class Functor :: (Type -> Type) -> Constraint
class Functor f where
A Functor
is a type constructor which supports a mapping operation
map
.
map
can be used to turn functions a -> b
into functions
f a -> f b
whose argument and return types use the type constructor f
to represent some computational context.
Instances must satisfy the following laws:
- Identity:
map identity = identity
- Composition:
map (f <<< g) = map f <<< map g
Members
map :: forall a b. (a -> b) -> f a -> f b
Instances
#void Source
void :: forall f a. Functor f => f a -> f Unit
The void
function is used to ignore the type wrapped by a
Functor
, replacing it with Unit
and keeping only the type
information provided by the type constructor itself.
void
is often useful when using do
notation to change the return type
of a monadic computation:
main = forE 1 10 \n -> void do
print n
print (n * n)
The
bind
/>>=
function forArray
works by applying a function to each element in the array, and flattening the results into a single, new array.Array's
bind
/>>=
works like a nested for loop. Eachbind
adds another level of nesting in the loop. For example: