-- 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
--   
-- -- -- --
--   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
--   
-- -- -- --
--   select = selectM
--   
-- -- There are also a few useful theorems: -- -- -- --
--   f <$> select x y = select (fmap f <$> x) (fmap f <$> y)
--   
-- -- -- --
--   select (first f <$> x) y = select x ((. f) <$> y)
--   
-- -- -- --
--   select x (f <$> y) = select (first (flip f) <$> x) (flip ($) <$> y)
--   
-- -- -- --
--   x <*? pure y = either y id <$> x
--   
-- -- -- --
--   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: -- -- 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)