Portability | portable |
---|---|
Stability | experimental |
Maintainer | Merijn Verstraaten <merijn@inconsistent.nl> |
Safe Haskell | Safe-Inferred |
Control.Applicative.Supply
Contents
Description
- Computation type:
- Computations that require a supply of values.
- Binding strategy:
- Applicative values are functions that consume an input from a supply to produce a value.
- Useful for:
- Providing a supply of unique names or other values to computations needing them.
- Zero and plus:
- Identical to the underlying implementation (if any) of
empty
and<|>
. - Example type:
-
orSupply
s aSupplyT
s f a - Difference from Control.Monad.Trans.Supply:
-
SupplyT
defined in this module is not, and cannot be an instance ofMonad
. See the Applicative vs Monad section below for an in-depth explanation.
The
applicative represents a computation that consumes a
supply of Supply
s as
's to produce a value of type a
. One example use is to
simplify computations that require the generation of unique names. The
Supply
applicative can be used to provide a stream of unique names to such
a computation.
- type Supply s a = SupplyT s Identity a
- data SupplyT s f a
- supply :: (s -> f a) -> SupplyT s f a
- provide :: Applicative f => (s -> a) -> SupplyT s f a
- demand :: Applicative f => SupplyT s f s
- withSupply :: (s' -> s) -> Supply s a -> Supply s' a
- withSupplyT :: (s' -> s) -> SupplyT s f a -> SupplyT s' f a
- runSupply :: Supply s a -> (s -> s) -> s -> a
- runSupplyT :: SupplyT s f a -> (s -> s) -> s -> f a
- runListSupply :: Supply s a -> [s] -> Either (Supply s a) a
- runListSupplyT :: SupplyT s f a -> [s] -> Either (SupplyT s f a) (f a)
- runMonadSupply :: Monad m => Supply s a -> m s -> m a
- runMonadSupplyT :: Monad m => SupplyT s f a -> m s -> m (f a)
Applicative vs Monad SupplyT
𝐓𝐋;𝐃𝐑: If you're wrapping a Monad
, use Control.Monad.Trans.Supply.
As mentioned above, the implementation of
SupplyT
in this module is not an instance of
Monad
and cannot be made one. While the implementation in
Control.Monad.Trans.Supply can be made a Monad
instance, this extra
power comes at a cost.
Specifically, SupplyT
cannot be made an
instance of Applicative
, unless the wrapped type is a Monad
. That is,
making 'SupplyT s f a'
an Applicative
requires that f
is a Monad
. As
a result, we cannot wrap something that is only an Applicative
without
losing the ability to compose computations in an applicative style.
The SupplyT
defined in this module exists to compliment the
SupplyT
with a transformer than can have an
Applicative
instance when the wrapped type is not a Monad
, at the cost
of not being able to wrap a Monad
.
If the type you're wrapping has a Monad
instance, you should use the
transformer from Control.Monad.Trans.Supply as it is more powerful than
this one.
Applicative Transformer?!
You might be wondering, "Why define SupplyT
in a transformer style? You
can already compose Applicative
s using Data.Functor.Compose!". The main
reason for this is that, this way people don't have to deal with newtype
(un)wrapping, and I don't have to come up with a way to disambiguate the
transformed and untransformed versions of demand
and provide
, as they
now work for both the transformed and untransformed case.
Supply and SupplyT Type
The Supply transformer.
Composes Supply with an underlying applicative, identical to using
, but this implementation avoids the
need to explicitly wrap Compose
Supply
f ademand
in pure
everywhere.
The resulting SupplyT value has an Alternative
instance if the underlying
applicative has an Alternative
instance.
Instances
Functor f => Functor (SupplyT s f) | |
Applicative f => Applicative (SupplyT s f) | |
Alternative f => Alternative (SupplyT s f) |
Supply Operations
supply :: (s -> f a) -> SupplyT s f aSource
Supply a construction function with an s
value from the supply.
provide :: Applicative f => (s -> a) -> SupplyT s f aSource
Supply a non-applicative construction function with an s
value from
the supply and automatically lift its result into the f
applicative that
SupplyT
wraps.
demand :: Applicative f => SupplyT s f sSource
Demand an s
value from the supply.
withSupply :: (s' -> s) -> Supply s a -> Supply s' aSource
Change the type of values consumed by a Supply
computation.
withSupplyT :: (s' -> s) -> SupplyT s f a -> SupplyT s' f aSource
Change the type of values consumed by a SupplyT
computation.
Running Supply Computations
runSupply :: Supply s a -> (s -> s) -> s -> aSource
Run a supply consuming computation, using a generation function and
initial value to compute the values consumed by the Supply
computation.
runSupplyT :: SupplyT s f a -> (s -> s) -> s -> f aSource
Run a supply consuming computation, using a generation function and
initial value to compute the values consumed by the SupplyT
computation.
runListSupply :: Supply s a -> [s] -> Either (Supply s a) aSource
Feed a supply consuming computation from a list until the computation
finishes or the list runs out. If the list does not contain sufficient
elements, runListSupply
returns uncompleted computation.
runListSupplyT :: SupplyT s f a -> [s] -> Either (SupplyT s f a) (f a)Source
Feed a supply consuming computation from a list until the computation
finishes or the list runs out. If the list does not contain sufficient
elements, runListSupplyT
returns uncompleted computation.
runMonadSupply :: Monad m => Supply s a -> m s -> m aSource
Feed a supply consuming computation from a monadic action until the computation finishes.
runMonadSupplyT :: Monad m => SupplyT s f a -> m s -> m (f a)Source
Feed a supply consuming computation from a monadic action until the computation finishes.