Control.Applicative.Free.Fast

free-5.2: Monads for free

Safe Haskell | Safe
Language | Haskell2010

Control.Applicative.Free.Fast

Contents

- The Sequence of Effects
- The Faster Free Applicative

Description

A faster free applicative. Based on Dave Menendez's work.

Synopsis

- data ASeq (f :: Type -> Type) a where
  - ANil :: forall (f :: Type -> Type). ASeq f ()
  - ACons :: forall (f :: Type -> Type) a1 u. f a1 -> ASeq f u -> ASeq f (a1, u)
- reduceASeq :: Applicative f => ASeq f u -> f u
- hoistASeq :: (forall x. f x -> g x) -> ASeq f a -> ASeq g a
- traverseASeq :: Applicative h => (forall x. f x -> h (g x)) -> ASeq f a -> h (ASeq g a)
- rebaseASeq :: forall (f :: Type -> Type) u y z v. ASeq f u -> (forall x. (x -> y) -> ASeq f x -> z) -> (v -> u -> y) -> ASeq f v -> z
- newtype Ap (f :: Type -> Type) a = Ap {
  - unAp :: forall u y z. (forall x. (x -> y) -> ASeq f x -> z) -> (u -> a -> y) -> ASeq f u -> z
  }
- liftAp :: f a -> Ap f a
- retractAp :: Applicative f => Ap f a -> f a
- runAp :: Applicative g => (forall x. f x -> g x) -> Ap f a -> g a
- runAp_ :: Monoid m => (forall a. f a -> m) -> Ap f b -> m
- hoistAp :: (forall x. f x -> g x) -> Ap f a -> Ap g a

# The Sequence of Effects

data ASeq (f :: Type -> Type) a where #

The free applicative is composed of a sequence of effects, and a pure function to apply that sequence to. The fast free applicative separates these from each other, so that the sequence may be built up independently, and so that `fmap` can run in constant time by having immediate access to the pure function.

Constructors

ANil :: forall (f :: Type -> Type). ASeq f () |
ACons :: forall (f :: Type -> Type) a1 u. f a1 -> ASeq f u -> ASeq f (a1, u) |

reduceASeq :: Applicative f => ASeq f u -> f u #

Interprets the sequence of effects using the semantics for `pure` and `<*>` given by the Applicative instance for `f`.

hoistASeq :: (forall x. f x -> g x) -> ASeq f a -> ASeq g a #

Given a natural transformation from `f` to `g` this gives a natural transformation from `ASeq f` to `ASeq g`.

traverseASeq :: Applicative h => (forall x. f x -> h (g x)) -> ASeq f a -> h (ASeq g a) #

Traverse a sequence with resepect to its interpretation type `f`.

rebaseASeq :: forall (f :: Type -> Type) u y z v. ASeq f u -> (forall x. (x -> y) -> ASeq f x -> z) -> (v -> u -> y) -> ASeq f v -> z #

It may not be obvious, but this essentially acts like ++, traversing the first sequence and creating a new one by appending the second sequence. The difference is that this also has to modify the return functions and that the return type depends on the input types.

See the source of `hoistAp` as an example usage.

# The Faster Free Applicative

newtype Ap (f :: Type -> Type) a #

The faster free `Applicative`.

Constructors

Ap |
Fields unAp :: forall u y z. (forall x. (x -> y) -> ASeq f x -> z) -> (u -> a -> y) -> ASeq f u -> z

#### Instances

Instances details

Applicative (Ap f) # |
Instance details Defined in Control.Applicative.Free.Fast Methods pure :: a -> Ap f a # (<*>) :: Ap f (a -> b) -> Ap f a -> Ap f b # liftA2 :: (a -> b -> c) -> Ap f a -> Ap f b -> Ap f c # (*>) :: Ap f a -> Ap f b -> Ap f b # (<*) :: Ap f a -> Ap f b -> Ap f a #
Functor (Ap f) # |
Instance details Defined in Control.Applicative.Free.Fast Methods fmap :: (a -> b) -> Ap f a -> Ap f b # (<$) :: a -> Ap f b -> Ap f a #
Apply (Ap f) # |
Instance details Defined in Control.Applicative.Free.Fast Methods (<.>) :: Ap f (a -> b) -> Ap f a -> Ap f b # (.>) :: Ap f a -> Ap f b -> Ap f b # (<.) :: Ap f a -> Ap f b -> Ap f a # liftF2 :: (a -> b -> c) -> Ap f a -> Ap f b -> Ap f c #

liftAp :: f a -> Ap f a #

A version of `lift` that can be used with just a `Functor` for `f`.

retractAp :: Applicative f => Ap f a -> f a #

Interprets the free applicative functor over f using the semantics for `pure` and `<*>` given by the Applicative instance for f.

    retractApp == runAp id

runAp :: Applicative g => (forall x. f x -> g x) -> Ap f a -> g a #

Given a natural transformation from `f` to `g`, this gives a canonical monoidal natural transformation from ``Ap` f` to `g`.

    runAp t == retractApp . hoistApp t

runAp_ :: Monoid m => (forall a. f a -> m) -> Ap f b -> m #

Perform a monoidal analysis over free applicative value.

Example:

    count :: Ap f a -> Int
    count = getSum . runAp_ (\_ -> Sum 1)

hoistAp :: (forall x. f x -> g x) -> Ap f a -> Ap g a #

Given a natural transformation from `f` to `g` this gives a monoidal natural transformation from `Ap f` to `Ap g`.