selective-0.5: 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:
• 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 Instances details  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

Instances details
 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 # 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 Instances details  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

Instances details

# 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

Instances details
 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] #