transformers-supply-0.1.0: Supply applicative, monad, applicative transformer and monad transformer.

Portabilityportable
Stabilityexperimental
MaintainerMerijn Verstraaten <merijn@inconsistent.nl>
Safe HaskellSafe-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:
Supply s a   or   SupplyT s f a
Difference from Control.Monad.Trans.Supply:
SupplyT defined in this module is not, and cannot be an instance of Monad. See the Applicative vs Monad section below for an in-depth explanation.

The Supply s a applicative represents a computation that consumes a supply of s'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.

Synopsis

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

type Supply s a = SupplyT s Identity aSource

The Supply applicative.

Computations consume values of type s from a supply of values.

pure ignores the supply of values, while <*> passes the supply to the second argument after the first argument is done consuming values.

data SupplyT s f a Source

The Supply transformer.

Composes Supply with an underlying applicative, identical to using Compose Supply f a, but this implementation avoids the need to explicitly wrap demand in pure everywhere.

The resulting SupplyT value has an Alternative instance if the underlying applicative has an Alternative instance.

Instances

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.