| 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
emptyand<|>. - Example type:
-
orSupplys aSupplyTs f a - Difference from Control.Monad.Trans.Supply:
-
SupplyTdefined 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 Applicatives 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.