-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Selective applicative functors
--
-- Selective applicative functors: declare your effects statically,
-- select which to execute dynamically.
--
-- This is a library for selective applicative functors, or just
-- selective functors for short, an abstraction between
-- applicative functors and monads, introduced in this paper.
@package selective
@version 0.2
-- | This is a library for selective applicative functors, or just
-- selective functors for short, an abstraction between
-- applicative functors and monads, introduced in this paper:
-- https://www.staff.ncl.ac.uk/andrey.mokhov/selective-functors.pdf.
module Control.Selective
-- | Selective applicative functors. You can think of select as a
-- selective function application: when given a value of type Left
-- a, you must apply the given function, but when given a
-- Right b, you may skip the function and associated
-- effects, and simply return the b.
--
-- Note that it is not a requirement for selective functors to skip
-- unnecessary effects. It may be counterintuitive, but this makes them
-- more useful. Why? Typically, when executing a selective computation,
-- you would want to skip the effects (saving work); but on the other
-- hand, if your goal is to statically analyse a given selective
-- computation and extract the set of all possible effects (without
-- actually executing them), then you do not want to skip any effects,
-- because that defeats the purpose of static analysis.
--
-- The type signature of select is reminiscent of both
-- <*> and >>=, and indeed a selective functor
-- is in some sense a composition of an applicative functor and the
-- Either monad.
--
-- Laws:
--
--
--
--
-- x <*? pure id = either id id <$> x
--
--
--
-- - Distributivity; note that y and z have the same
-- type f (a -> b):
--
--
--
-- pure x <*? (y *> z) = (pure x <*? y) *> (pure x <*? z)
--
--
--
--
--
-- x <*? (y <*? z) = (f <$> x) <*? (g <$> y) <*? (h <$> z)
-- where
-- f x = Right <$> x
-- g y = a -> bimap (,a) ($a) y
-- h z = uncurry z
--
--
--
-- - Monadic select (for selective functors that are also
-- monads):
--
--
--
-- select = selectM
--
--
-- There are also a few useful theorems:
--
--
-- - Apply a pure function to the result:
--
--
--
-- f <$> select x y = select (fmap f <$> x) (fmap f <$> y)
--
--
--
-- - Apply a pure function to the Left case of the first
-- argument:
--
--
--
-- select (first f <$> x) y = select x ((. f) <$> y)
--
--
--
-- - Apply a pure function to the second argument:
--
--
--
-- select x (f <$> y) = select (first (flip f) <$> x) (flip ($) <$> y)
--
--
--
-- - Generalised identity:
--
--
--
-- x <*? pure y = either y id <$> x
--
--
--
-- - A selective functor is rigid if it satisfies <*>
-- = apS. The following interchange law holds for rigid
-- selective functors:
--
--
--
-- x *> (y <*? z) = (x *> y) <*? z
--
--
-- If f is also a Monad, we require that select =
-- selectM, from which one can prove <*> = apS.
class Applicative f => Selective f
select :: Selective f => f (Either a b) -> f (a -> b) -> f b
-- | An operator alias for select, which is sometimes convenient. It
-- tries to follow the notational convention for Applicative
-- operators. The angle bracket pointing to the left means we always use
-- the corresponding value. The value on the right, however, may be
-- skipped, hence the question mark.
(<*?) :: Selective f => f (Either a b) -> f (a -> b) -> f b
infixl 4 <*?
-- | The branch function is a natural generalisation of
-- select: instead of skipping an unnecessary effect, it chooses
-- which of the two given effectful functions to apply to a given
-- argument; the other effect is unnecessary. It is possible to implement
-- branch in terms of select, which is a good puzzle (give
-- it a try!).
branch :: Selective f => f (Either a b) -> f (a -> c) -> f (b -> c) -> f c
-- | We can write a function with the type signature of select using
-- the Applicative type class, but it will always execute the
-- effects associated with the second argument, hence being potentially
-- less efficient.
selectA :: Applicative f => f (Either a b) -> f (a -> b) -> f b
-- | Recover the application operator <*> from
-- select. Rigid selective functors satisfy the law
-- (<*>) = apS and furthermore, the resulting applicative
-- functor satisfies all laws of Applicative:
--
--
-- - Identity:
pure id <*> v = v
-- - Homomorphism:
pure f <*> pure x = pure (f x)
-- - Interchange:
u <*> pure y = pure ($y) <*>
-- u
-- - Composition:
(.) <$> u <*> v <*> w = u
-- <*> (v <*> w)
--
apS :: Selective f => f (a -> b) -> f a -> f b
-- | One can easily implement a monadic selectM that satisfies the
-- laws, hence any Monad is Selective.
selectM :: Monad f => f (Either a b) -> f (a -> b) -> f b
-- | Branch on a Boolean value, skipping unnecessary effects.
ifS :: Selective f => f Bool -> f a -> f a -> f a
-- | Conditionally perform an effect.
whenS :: Selective f => f Bool -> f () -> f ()
-- | A lifted version of fromMaybe.
fromMaybeS :: Selective f => f a -> f (Maybe a) -> f a
-- | Return the first Right value. If both are Left's,
-- accumulate errors.
orElse :: (Selective f, Semigroup e) => f (Either e a) -> f (Either e a) -> f (Either e a)
-- | Accumulate the Right values, or return the first
-- Left.
andAlso :: (Selective f, Semigroup a) => f (Either e a) -> f (Either e a) -> f (Either e a)
-- | Keep running an effectful computation until it returns a
-- Right value, collecting the Left's using a supplied
-- Monoid instance.
untilRight :: (Monoid a, Selective f) => f (Either a b) -> f (a, b)
-- | Keep checking an effectful condition while it holds.
whileS :: Selective f => f Bool -> f ()
-- | A lifted version of lazy Boolean OR.
(<||>) :: Selective f => f Bool -> f Bool -> f Bool
-- | A lifted version of lazy Boolean AND.
(<&&>) :: Selective f => f Bool -> f Bool -> f Bool
-- | Generalised folding with the short-circuiting behaviour.
foldS :: (Selective f, Foldable t, Monoid a) => t (f (Either e a)) -> f (Either e a)
-- | A lifted version of any. Retains the short-circuiting
-- behaviour.
anyS :: Selective f => (a -> f Bool) -> [a] -> f Bool
-- | A lifted version of all. Retains the short-circuiting
-- behaviour.
allS :: Selective f => (a -> f Bool) -> [a] -> f Bool
-- | A restricted version of monadic bind. Fails with an error if the
-- Bounded and Enum instances for a do not cover
-- all values of a.
bindS :: (Bounded a, Enum a, Eq a, Selective f) => f a -> (a -> f b) -> f b
-- | A list of values, equipped with a fast membership test.
data Cases a
-- | The list of all possible values of an enumerable data type.
casesEnum :: (Bounded a, Enum a) => Cases a
-- | Embed a list of values into Cases using the trivial but slow
-- membership test based on elem.
cases :: Eq a => [a] -> Cases a
-- | Eliminate all specified values a from f (Either a b)
-- by replacing each of them with a given f a.
matchS :: (Eq a, Selective f) => Cases a -> f a -> (a -> f b) -> f (Either a b)
-- | Eliminate all specified values a from f (Either a b)
-- by replacing each of them with a given f a.
matchM :: Monad m => Cases a -> m a -> (a -> m b) -> m (Either a b)
-- | Any applicative functor can be given a Selective instance by
-- defining select = selectA.
newtype SelectA f a
SelectA :: f a -> SelectA f a
[fromSelectA] :: SelectA f a -> f a
-- | Any monad can be given a Selective instance by defining
-- select = selectM.
newtype SelectM f a
SelectM :: f a -> SelectM f a
[fromSelectM] :: SelectM f a -> f a
-- | Static analysis of selective functors with over-approximation.
newtype Over m a
Over :: m -> Over m a
[getOver] :: Over m a -> m
-- | Static analysis of selective functors with under-approximation.
newtype Under m a
Under :: m -> Under m a
[getUnder] :: Under m a -> m
-- | Selective instance for the standard applicative functor Validation.
-- This is a good example of a selective functor which is not a monad.
data Validation e a
Failure :: e -> Validation e a
Success :: a -> Validation e a
instance GHC.Base.Functor f => GHC.Base.Functor (Control.Selective.ComposeEither f e)
instance (GHC.Show.Show e, GHC.Show.Show a) => GHC.Show.Show (Control.Selective.Validation e a)
instance GHC.Base.Functor (Control.Selective.Validation e)
instance GHC.Show.Show m => GHC.Show.Show (Control.Selective.Under m a)
instance GHC.Classes.Ord m => GHC.Classes.Ord (Control.Selective.Under m a)
instance GHC.Base.Functor (Control.Selective.Under m)
instance GHC.Classes.Eq m => GHC.Classes.Eq (Control.Selective.Under m a)
instance GHC.Show.Show m => GHC.Show.Show (Control.Selective.Over m a)
instance GHC.Classes.Ord m => GHC.Classes.Ord (Control.Selective.Over m a)
instance GHC.Base.Functor (Control.Selective.Over m)
instance GHC.Classes.Eq m => GHC.Classes.Eq (Control.Selective.Over m a)
instance GHC.Base.Monad f => GHC.Base.Monad (Control.Selective.SelectM f)
instance GHC.Base.Applicative f => GHC.Base.Applicative (Control.Selective.SelectM f)
instance GHC.Base.Functor f => GHC.Base.Functor (Control.Selective.SelectM f)
instance GHC.Base.Applicative f => GHC.Base.Applicative (Control.Selective.SelectA f)
instance GHC.Base.Functor f => GHC.Base.Functor (Control.Selective.SelectA f)
instance GHC.Base.Applicative f => GHC.Base.Applicative (Control.Selective.ComposeEither f e)
instance (Control.Selective.Selective f, GHC.Base.Monoid e) => GHC.Base.Alternative (Control.Selective.ComposeEither f e)
instance GHC.Base.Semigroup e => GHC.Base.Applicative (Control.Selective.Validation e)
instance GHC.Base.Semigroup e => Control.Selective.Selective (Control.Selective.Validation e)
instance GHC.Base.Monoid m => GHC.Base.Applicative (Control.Selective.Under m)
instance GHC.Base.Monoid m => Control.Selective.Selective (Control.Selective.Under m)
instance GHC.Base.Monoid m => GHC.Base.Applicative (Control.Selective.Over m)
instance GHC.Base.Monoid m => Control.Selective.Selective (Control.Selective.Over m)
instance GHC.Base.Monad f => Control.Selective.Selective (Control.Selective.SelectM f)
instance GHC.Base.Applicative f => Control.Selective.Selective (Control.Selective.SelectA f)
instance Control.Selective.Selective f => Control.Selective.Selective (Control.Applicative.Lift.Lift f)
instance Control.Selective.Selective Control.Applicative.ZipList
instance (Control.Selective.Selective f, Control.Selective.Selective g) => Control.Selective.Selective (Data.Functor.Product.Product f g)
instance (GHC.Base.Applicative f, Control.Selective.Selective g) => Control.Selective.Selective (Data.Functor.Compose.Compose f g)
instance Control.Selective.Selective GHC.Types.IO
instance Control.Selective.Selective []
instance GHC.Base.Monoid a => Control.Selective.Selective ((,) a)
instance Control.Selective.Selective ((->) a)
instance Control.Selective.Selective (Data.Either.Either e)
instance Control.Selective.Selective Data.Functor.Identity.Identity
instance Control.Selective.Selective GHC.Maybe.Maybe
instance Control.Selective.Selective GHC.Base.NonEmpty
instance Control.Selective.Selective Data.Proxy.Proxy
instance Control.Selective.Selective (GHC.ST.ST s)
instance Control.Selective.Selective GHC.Conc.Sync.STM
instance Control.Selective.Selective (Control.Monad.Trans.Cont.ContT r m)
instance GHC.Base.Monad m => Control.Selective.Selective (Control.Monad.Trans.Except.ExceptT e m)
instance GHC.Base.Monad m => Control.Selective.Selective (Control.Monad.Trans.Identity.IdentityT m)
instance GHC.Base.Monad m => Control.Selective.Selective (Control.Monad.Trans.Maybe.MaybeT m)
instance GHC.Base.Monad m => Control.Selective.Selective (Control.Monad.Trans.Reader.ReaderT r m)
instance (GHC.Base.Monoid w, GHC.Base.Monad m) => Control.Selective.Selective (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
instance (GHC.Base.Monoid w, GHC.Base.Monad m) => Control.Selective.Selective (Control.Monad.Trans.RWS.Strict.RWST r w s m)
instance GHC.Base.Monad m => Control.Selective.Selective (Control.Monad.Trans.State.Lazy.StateT s m)
instance GHC.Base.Monad m => Control.Selective.Selective (Control.Monad.Trans.State.Strict.StateT s m)
instance (GHC.Base.Monoid w, GHC.Base.Monad m) => Control.Selective.Selective (Control.Monad.Trans.Writer.Lazy.WriterT w m)
instance (GHC.Base.Monoid w, GHC.Base.Monad m) => Control.Selective.Selective (Control.Monad.Trans.Writer.Strict.WriterT w m)
instance Control.Arrow.ArrowChoice a => Control.Selective.Selective (Control.Arrow.ArrowMonad a)
-- | This is a library for selective applicative functors, or just
-- selective functors for short, an abstraction between
-- applicative functors and monads, introduced in this paper:
-- https://www.staff.ncl.ac.uk/andrey.mokhov/selective-functors.pdf.
--
-- This module defines free selective functors using the ideas
-- from the Sjoerd Visscher's package 'free-functors':
-- https://hackage.haskell.org/package/free-functors-1.0.1/docs/Data-Functor-HFree.html.
module Control.Selective.Free
-- | Free selective functors.
newtype Select f a
Select :: (forall g. Selective g => (forall x. f x -> g x) -> g a) -> Select f a
-- | Lift a functor into a free selective computation.
liftSelect :: f a -> Select f a
-- | Extract the resulting value if there are no necessary effects.
getPure :: Select f a -> Maybe a
-- | Collect all possible effects in the order they appear in a free
-- selective computation.
getEffects :: Functor f => Select f a -> [f ()]
-- | Extract all necessary effects in the order they appear in a
-- free selective computation.
getNecessaryEffects :: Functor f => Select f a -> [f ()]
-- | Given a natural transformation from f to g, this
-- gives a canonical natural transformation from Select f to
-- g. Note that here we rely on the fact that g is a
-- lawful selective functor.
runSelect :: Selective g => (forall x. f x -> g x) -> Select f a -> g a
-- | Concatenate all effects of a free selective computation.
foldSelect :: Monoid m => (forall x. f x -> m) -> Select f a -> m
instance GHC.Base.Functor (Control.Selective.Free.Select f)
instance GHC.Base.Applicative (Control.Selective.Free.Select f)
instance Control.Selective.Selective (Control.Selective.Free.Select f)
-- | This is a library for selective applicative functors, or just
-- selective functors for short, an abstraction between
-- applicative functors and monads, introduced in this paper:
-- https://www.staff.ncl.ac.uk/andrey.mokhov/selective-functors.pdf.
--
-- This module defines free rigid selective functors, i.e. for
-- selective functors satisfying the property <*> = apS.
module Control.Selective.Free.Rigid
-- | Free rigid selective functors.
data Select f a
[Pure] :: a -> Select f a
[Select] :: Select f (Either a b) -> f (a -> b) -> Select f b
-- | Lift a functor into a free selective computation.
liftSelect :: Functor f => f a -> Select f a
-- | Extract the resulting value if there are no necessary effects.
getPure :: Select f a -> Maybe a
-- | Collect all possible effects in the order they appear in a free
-- selective computation.
getEffects :: Functor f => Select f a -> [f ()]
-- | Extract the necessary effect from a free selective computation. Note:
-- there can be at most one effect that is statically guaranteed to be
-- necessary.
getNecessaryEffect :: Functor f => Select f a -> Maybe (f ())
-- | Given a natural transformation from f to g, this
-- gives a canonical natural transformation from Select f to
-- g.
runSelect :: Selective g => (forall x. f x -> g x) -> Select f a -> g a
-- | Concatenate all effects of a free selective computation.
foldSelect :: Monoid m => (forall x. f x -> m) -> Select f a -> m
instance GHC.Base.Functor f => GHC.Base.Functor (Control.Selective.Free.Rigid.Select f)
instance GHC.Base.Functor f => GHC.Base.Applicative (Control.Selective.Free.Rigid.Select f)
instance GHC.Base.Functor f => Control.Selective.Selective (Control.Selective.Free.Rigid.Select f)