selective-0.4.1: Selective applicative functors

Control.Selective

Description

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.

Synopsis

# Type class

class Applicative f => Selective f where Source #

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:

• Identity:
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)  • Associativity: 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) ((&) <$> 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. Methods select :: f (Either a b) -> f (a -> b) -> f b Source # Instances  Source # Instance detailsDefined in Control.Selective Methodsselect :: [Either a b] -> [a -> b] -> [b] Source # Source # Instance detailsDefined in Control.Selective Methodsselect :: Maybe (Either a b) -> Maybe (a -> b) -> Maybe b Source # Source # Instance detailsDefined in Control.Selective Methodsselect :: IO (Either a b) -> IO (a -> b) -> IO b Source # Source # Instance detailsDefined in Control.Selective Methodsselect :: ZipList (Either a b) -> ZipList (a -> b) -> ZipList b Source # Source # Instance detailsDefined in Control.Selective Methodsselect :: Identity (Either a b) -> Identity (a -> b) -> Identity b Source # Source # Instance detailsDefined in Control.Selective Methodsselect :: STM (Either a b) -> STM (a -> b) -> STM b Source # Source # Instance detailsDefined in Control.Selective Methodsselect :: NonEmpty (Either a b) -> NonEmpty (a -> b) -> NonEmpty b Source # Source # Instance detailsDefined in Control.Selective Methodsselect :: Either e (Either a b) -> Either e (a -> b) -> Either e b Source # Monoid a => Selective ((,) a) Source # Instance detailsDefined in Control.Selective Methodsselect :: (a, Either a0 b) -> (a, a0 -> b) -> (a, b) Source # Selective (ST s) Source # Instance detailsDefined in Control.Selective Methodsselect :: ST s (Either a b) -> ST s (a -> b) -> ST s b Source # Source # Instance detailsDefined in Control.Selective Methodsselect :: ArrowMonad a (Either a0 b) -> ArrowMonad a (a0 -> b) -> ArrowMonad a b Source # Selective (Proxy :: Type -> Type) Source # Instance detailsDefined in Control.Selective Methodsselect :: Proxy (Either a b) -> Proxy (a -> b) -> Proxy b Source # Selective f => Selective (Lift f) Source # Instance detailsDefined in Control.Selective Methodsselect :: Lift f (Either a b) -> Lift f (a -> b) -> Lift f b Source # Monad m => Selective (MaybeT m) Source # Instance detailsDefined in Control.Selective Methodsselect :: MaybeT m (Either a b) -> MaybeT m (a -> b) -> MaybeT m b Source # Semigroup e => Selective (Validation e) Source # Instance detailsDefined in Control.Selective Methodsselect :: Validation e (Either a b) -> Validation e (a -> b) -> Validation e b Source # Monoid m => Selective (Under m) Source # Instance detailsDefined in Control.Selective Methodsselect :: Under m (Either a b) -> Under m (a -> b) -> Under m b Source # Monoid m => Selective (Over m) Source # Instance detailsDefined in Control.Selective Methodsselect :: Over m (Either a b) -> Over m (a -> b) -> Over m b Source # Monad f => Selective (SelectM f) Source # Instance detailsDefined in Control.Selective Methodsselect :: SelectM f (Either a b) -> SelectM f (a -> b) -> SelectM f b Source # Applicative f => Selective (SelectA f) Source # Instance detailsDefined in Control.Selective Methodsselect :: SelectA f (Either a b) -> SelectA f (a -> b) -> SelectA f b Source # Source # Instance detailsDefined in Control.Selective.Free Methodsselect :: Select f (Either a b) -> Select f (a -> b) -> Select f b Source # Functor f => Selective (Select f) Source # Instance detailsDefined in Control.Selective.Rigid.Free Methodsselect :: Select f (Either a b) -> Select f (a -> b) -> Select f b Source # Source # Instance detailsDefined in Control.Selective.Rigid.Freer Methodsselect :: Select f (Either a b) -> Select f (a -> b) -> Select f b Source # (Monoid w, Monad m) => Selective (WriterT w m) Source # Instance detailsDefined in Control.Selective Methodsselect :: WriterT w m (Either a b) -> WriterT w m (a -> b) -> WriterT w m b Source # (Monoid w, Monad m) => Selective (WriterT w m) Source # Instance detailsDefined in Control.Selective Methodsselect :: WriterT w m (Either a b) -> WriterT w m (a -> b) -> WriterT w m b Source # Monad m => Selective (StateT s m) Source # Instance detailsDefined in Control.Selective Methodsselect :: StateT s m (Either a b) -> StateT s m (a -> b) -> StateT s m b Source # Monad m => Selective (StateT s m) Source # Instance detailsDefined in Control.Selective Methodsselect :: StateT s m (Either a b) -> StateT s m (a -> b) -> StateT s m b Source # Monad m => Selective (IdentityT m) Source # Instance detailsDefined in Control.Selective Methodsselect :: IdentityT m (Either a b) -> IdentityT m (a -> b) -> IdentityT m b Source # Monad m => Selective (ExceptT e m) Source # Instance detailsDefined in Control.Selective Methodsselect :: ExceptT e m (Either a b) -> ExceptT e m (a -> b) -> ExceptT e m b Source # Selective ((->) a :: Type -> Type) Source # Instance detailsDefined in Control.Selective Methodsselect :: (a -> Either a0 b) -> (a -> (a0 -> b)) -> a -> b Source # (Selective f, Selective g) => Selective (Product f g) Source # Instance detailsDefined in Control.Selective Methodsselect :: Product f g (Either a b) -> Product f g (a -> b) -> Product f g b Source # Monad m => Selective (ReaderT r m) Source # Instance detailsDefined in Control.Selective Methodsselect :: ReaderT r m (Either a b) -> ReaderT r m (a -> b) -> ReaderT r m b Source # Selective (ContT r m) Source # Instance detailsDefined in Control.Selective Methodsselect :: ContT r m (Either a b) -> ContT r m (a -> b) -> ContT r m b Source # (Applicative f, Selective g) => Selective (Compose f g) Source # Instance detailsDefined in Control.Selective Methodsselect :: Compose f g (Either a b) -> Compose f g (a -> b) -> Compose f g b Source # (Monoid w, Monad m) => Selective (RWST r w s m) Source # Instance detailsDefined in Control.Selective Methodsselect :: RWST r w s m (Either a b) -> RWST r w s m (a -> b) -> RWST r w s m b Source # (Monoid w, Monad m) => Selective (RWST r w s m) Source # Instance detailsDefined in Control.Selective Methodsselect :: RWST r w s m (Either a b) -> RWST r w s m (a -> b) -> RWST r w s m b Source # (<*?) :: Selective f => f (Either a b) -> f (a -> b) -> f b infixl 4 Source # 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. branch :: Selective f => f (Either a b) -> f (a -> c) -> f (b -> c) -> f c Source # 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!). We can also implement select via branch: selectB :: Selective f => f (Either a b) -> f (a -> b) -> f b selectB x y = branch x y (pure id)  selectA :: Applicative f => f (Either a b) -> f (a -> b) -> f b Source # 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. apS :: Selective f => f (a -> b) -> f a -> f b Source # 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) selectM :: Monad f => f (Either a b) -> f (a -> b) -> f b Source # One can easily implement a monadic selectM that satisfies the laws, hence any Monad is Selective. # Conditional combinators ifS :: Selective f => f Bool -> f a -> f a -> f a Source # Branch on a Boolean value, skipping unnecessary effects. whenS :: Selective f => f Bool -> f () -> f () Source # Conditionally perform an effect. fromMaybeS :: Selective f => f a -> f (Maybe a) -> f a Source # A lifted version of fromMaybe. orElse :: (Selective f, Semigroup e) => f (Either e a) -> f (Either e a) -> f (Either e a) Source # Return the first Right value. If both are Left's, accumulate errors. andAlso :: (Selective f, Semigroup a) => f (Either e a) -> f (Either e a) -> f (Either e a) Source # Accumulate the Right values, or return the first Left. untilRight :: (Monoid a, Selective f) => f (Either a b) -> f (a, b) Source # Keep running an effectful computation until it returns a Right value, collecting the Left's using a supplied Monoid instance. whileS :: Selective f => f Bool -> f () Source # Keep checking an effectful condition while it holds. (<||>) :: Selective f => f Bool -> f Bool -> f Bool Source # A lifted version of lazy Boolean OR. (<&&>) :: Selective f => f Bool -> f Bool -> f Bool Source # A lifted version of lazy Boolean AND. foldS :: (Selective f, Foldable t, Monoid a) => t (f (Either e a)) -> f (Either e a) Source # Generalised folding with the short-circuiting behaviour. anyS :: Selective f => (a -> f Bool) -> [a] -> f Bool Source # A lifted version of any. Retains the short-circuiting behaviour. allS :: Selective f => (a -> f Bool) -> [a] -> f Bool Source # A lifted version of all. Retains the short-circuiting behaviour. bindS :: (Bounded a, Enum a, Eq a, Selective f) => f a -> (a -> f b) -> f b Source # 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. data Cases a Source # A list of values, equipped with a fast membership test. casesEnum :: (Bounded a, Enum a) => Cases a Source # The list of all possible values of an enumerable data type. cases :: Eq a => [a] -> Cases a Source # Embed a list of values into Cases using the trivial but slow membership test based on elem. matchS :: (Eq a, Selective f) => Cases a -> f a -> (a -> f b) -> f (Either a b) Source # 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) Source # Eliminate all specified values a from f (Either a b) by replacing each of them with a given f a. # Selective functors newtype SelectA f a Source # Any applicative functor can be given a Selective instance by defining select = selectA. This data type captures this pattern, so you can use it in combination with the DerivingVia extension as follows: newtype Over m a = Over m deriving (Functor, Applicative, Selective) via SelectA (Const m)  Constructors  SelectA FieldsgetSelectA :: f a Instances  Functor f => Functor (SelectA f) Source # Instance detailsDefined in Control.Selective Methodsfmap :: (a -> b) -> SelectA f a -> SelectA f b #(<$) :: a -> SelectA f b -> SelectA f a # Source # Instance detailsDefined in Control.Selective Methodspure :: a -> SelectA f a #(<*>) :: SelectA f (a -> b) -> SelectA f a -> SelectA f b #liftA2 :: (a -> b -> c) -> SelectA f a -> SelectA f b -> SelectA f c #(*>) :: SelectA f a -> SelectA f b -> SelectA f b #(<*) :: SelectA f a -> SelectA f b -> SelectA f a # Applicative f => Selective (SelectA f) Source # Instance detailsDefined in Control.Selective Methodsselect :: SelectA f (Either a b) -> SelectA f (a -> b) -> SelectA f b Source #

newtype SelectM f a Source #

Any monad can be given a Selective instance by defining select = selectM. This data type captures this pattern, so you can use it in combination with the DerivingVia extension as follows:

newtype V1 a = V1 a
deriving (Functor, Applicative, Selective, Monad) via SelectM Identity


Constructors

 SelectM FieldsgetSelectM :: f a
Instances
 Monad f => Monad (SelectM f) Source # Instance detailsDefined in Control.Selective Methods(>>=) :: SelectM f a -> (a -> SelectM f b) -> SelectM f b #(>>) :: SelectM f a -> SelectM f b -> SelectM f b #return :: a -> SelectM f a #fail :: String -> SelectM f a # Functor f => Functor (SelectM f) Source # Instance detailsDefined in Control.Selective Methodsfmap :: (a -> b) -> SelectM f a -> SelectM f b #(<$) :: a -> SelectM f b -> SelectM f a # Source # Instance detailsDefined in Control.Selective Methodspure :: a -> SelectM f a #(<*>) :: SelectM f (a -> b) -> SelectM f a -> SelectM f b #liftA2 :: (a -> b -> c) -> SelectM f a -> SelectM f b -> SelectM f c #(*>) :: SelectM f a -> SelectM f b -> SelectM f b #(<*) :: SelectM f a -> SelectM f b -> SelectM f a # Monad f => Selective (SelectM f) Source # Instance detailsDefined in Control.Selective Methodsselect :: SelectM f (Either a b) -> SelectM f (a -> b) -> SelectM f b Source # newtype Over m a Source # Static analysis of selective functors with over-approximation. Constructors  Over FieldsgetOver :: m Instances  Functor (Over m) Source # Instance detailsDefined in Control.Selective Methodsfmap :: (a -> b) -> Over m a -> Over m b #(<$) :: a -> Over m b -> Over m a # Monoid m => Applicative (Over m) Source # Instance detailsDefined in Control.Selective Methodspure :: a -> Over m a #(<*>) :: Over m (a -> b) -> Over m a -> Over m b #liftA2 :: (a -> b -> c) -> Over m a -> Over m b -> Over m c #(*>) :: Over m a -> Over m b -> Over m b #(<*) :: Over m a -> Over m b -> Over m a # Monoid m => Selective (Over m) Source # Instance detailsDefined in Control.Selective Methodsselect :: Over m (Either a b) -> Over m (a -> b) -> Over m b Source # Eq m => Eq (Over m a) Source # Instance detailsDefined in Control.Selective Methods(==) :: Over m a -> Over m a -> Bool #(/=) :: Over m a -> Over m a -> Bool # Ord m => Ord (Over m a) Source # Instance detailsDefined in Control.Selective Methodscompare :: Over m a -> Over m a -> Ordering #(<) :: Over m a -> Over m a -> Bool #(<=) :: Over m a -> Over m a -> Bool #(>) :: Over m a -> Over m a -> Bool #(>=) :: Over m a -> Over m a -> Bool #max :: Over m a -> Over m a -> Over m a #min :: Over m a -> Over m a -> Over m a # Show m => Show (Over m a) Source # Instance detailsDefined in Control.Selective MethodsshowsPrec :: Int -> Over m a -> ShowS #show :: Over m a -> String #showList :: [Over m a] -> ShowS #

newtype Under m a Source #

Static analysis of selective functors with under-approximation.

Constructors

 Under FieldsgetUnder :: m
Instances
 Functor (Under m) Source # Instance detailsDefined in Control.Selective Methodsfmap :: (a -> b) -> Under m a -> Under m b #(<$) :: a -> Under m b -> Under m a # Monoid m => Applicative (Under m) Source # Instance detailsDefined in Control.Selective Methodspure :: a -> Under m a #(<*>) :: Under m (a -> b) -> Under m a -> Under m b #liftA2 :: (a -> b -> c) -> Under m a -> Under m b -> Under m c #(*>) :: Under m a -> Under m b -> Under m b #(<*) :: Under m a -> Under m b -> Under m a # Monoid m => Selective (Under m) Source # Instance detailsDefined in Control.Selective Methodsselect :: Under m (Either a b) -> Under m (a -> b) -> Under m b Source # Eq m => Eq (Under m a) Source # Instance detailsDefined in Control.Selective Methods(==) :: Under m a -> Under m a -> Bool #(/=) :: Under m a -> Under m a -> Bool # Ord m => Ord (Under m a) Source # Instance detailsDefined in Control.Selective Methodscompare :: Under m a -> Under m a -> Ordering #(<) :: Under m a -> Under m a -> Bool #(<=) :: Under m a -> Under m a -> Bool #(>) :: Under m a -> Under m a -> Bool #(>=) :: Under m a -> Under m a -> Bool #max :: Under m a -> Under m a -> Under m a #min :: Under m a -> Under m a -> Under m a # Show m => Show (Under m a) Source # Instance detailsDefined in Control.Selective MethodsshowsPrec :: Int -> Under m a -> ShowS #show :: Under m a -> String #showList :: [Under m a] -> ShowS # data Validation e a Source # Selective instance for the standard applicative functor Validation. This is a good example of a non-trivial selective functor which is not a monad. Constructors  Failure e Success a Instances  Source # Instance detailsDefined in Control.Selective Methodsfmap :: (a -> b) -> Validation e a -> Validation e b #(<$) :: a -> Validation e b -> Validation e a # Source # Instance detailsDefined in Control.Selective Methodspure :: a -> Validation e a #(<*>) :: Validation e (a -> b) -> Validation e a -> Validation e b #liftA2 :: (a -> b -> c) -> Validation e a -> Validation e b -> Validation e c #(*>) :: Validation e a -> Validation e b -> Validation e b #(<*) :: Validation e a -> Validation e b -> Validation e a # Semigroup e => Selective (Validation e) Source # Instance detailsDefined in Control.Selective Methodsselect :: Validation e (Either a b) -> Validation e (a -> b) -> Validation e b Source # (Show e, Show a) => Show (Validation e a) Source # Instance detailsDefined in Control.Selective MethodsshowsPrec :: Int -> Validation e a -> ShowS #show :: Validation e a -> String #showList :: [Validation e a] -> ShowS #

# Miscellaneous

swapEither :: Either a b -> Either b a Source #

Swap Left and Right.

newtype ComposeEither f e a Source #

Composition of a functor f with the Either monad.

Constructors

 ComposeEither (f (Either e a))
Instances
 Functor f => Functor (ComposeEither f e) Source # Instance detailsDefined in Control.Selective Methodsfmap :: (a -> b) -> ComposeEither f e a -> ComposeEither f e b #(<\$) :: a -> ComposeEither f e b -> ComposeEither f e a # Applicative f => Applicative (ComposeEither f e) Source # Instance detailsDefined in Control.Selective Methodspure :: a -> ComposeEither f e a #(<*>) :: ComposeEither f e (a -> b) -> ComposeEither f e a -> ComposeEither f e b #liftA2 :: (a -> b -> c) -> ComposeEither f e a -> ComposeEither f e b -> ComposeEither f e c #(*>) :: ComposeEither f e a -> ComposeEither f e b -> ComposeEither f e b #(<*) :: ComposeEither f e a -> ComposeEither f e b -> ComposeEither f e a # (Selective f, Monoid e) => Alternative (ComposeEither f e) Source # Instance detailsDefined in Control.Selective Methodsempty :: ComposeEither f e a #(<|>) :: ComposeEither f e a -> ComposeEither f e a -> ComposeEither f e a #some :: ComposeEither f e a -> ComposeEither f e [a] #many :: ComposeEither f e a -> ComposeEither f e [a] #