can-i-haz-0.3.1.0: Generic implementation of the Has and CoHas patterns

Description

This module defines a class Has intended to be used with the MonadReader class or Reader / ReaderT types.

# The problem

Assume there are two types representing the MonadReader environments for different parts of an application:

data DbConfig = DbConfig { .. }
data WebConfig = WebConfig { .. }


as well as a single type containing both of those:

data AppEnv = AppEnv
{ dbConfig :: DbConfig
, webConfig :: WebConfig
}


What should be the MonadReader constraint of the DB module and web module respectively?

1. It could be MonadReader AppEnv m for both, introducing unnecessary coupling.
2. Or it could be MonadReader DbConfig m for the DB module and MonadReader WebConfig m for the web module respectively, but combining them becomes a pain.

Or, it could be MonadReader r m, Has DbConfig r for the DB module (and similarly for the web module), where some appropriately defined Has part record class allows projecting part out of some record. This approach keeps both modules decoupled, while allowing using them in the same monad stack.

The only downside is that now one has to define the Has class and write tediuos instances for the AppEnv type (and potentially other types in case of, for example, tests).

But why bother doing the work that the machine will happily do for you?

# The solution

This module defines the generic Has class as well as hides all the boilerplate behind GHC.Generics, so all you have to do is to add the corresponding deriving-clause:

data AppEnv = AppEnv
{ dbConfig :: DbConfig
, webConfig :: WebConfig
} deriving (Generic, Has DbConfig, Has WebConfig)


and use ask extract instead of ask (but this is something you'd have to do anyway).

# Type safety

What should happen if record does not have any field of type part at all? Of course, this means that we cannot project part out of record, and no Has instance can be derived at all. Indeed, this library will refuse to generate an instance in this case.

On the other hand, what should happen if record contains multiple values of type part, perhaps on different levels of nesting? While technically we could make an arbitrary choice, like taking the first one in breadth-first or depth-first order, we instead decide that such a choice is inherently ambiguous, so this library will refuse to generate an instance in this case as well.

# Updating the records, or poor man's lenses, and State

One we know that a value of type part is contained in record, we might easily update a record having a function that updates the part. This is done in the obvious way: we just locate the part in the record and update it!

Has has a method for this, called (unsurprisingly) update.

Note that this might be used for more composable functions living in State: now instead of MonadState StateType m we write (MonadState s m, Has StateType s) and use update and extract where necessary (likely in combination with modify and gets).

# Exports

This module also reexports Reader along with some functions like ask or reader with types adjusted for the intended usage of the Has class.

Synopsis

# Documentation

class Has part record where Source #

The Has part record class is used for records of type record supporting projecting out a value of type part.

Minimal complete definition

Nothing

Methods

extract :: record -> part Source #

Extract a subvalue of type part from the record.

The default implementation searches for some value of the type part in record and returns that value. The default implementation typechecks iff there is a single subvalue of type part in record.

extract :: forall path. (Generic record, SuccessfulSearch part record path) => record -> part Source #

Extract a subvalue of type part from the record.

The default implementation searches for some value of the type part in record and returns that value. The default implementation typechecks iff there is a single subvalue of type part in record.

update :: (part -> part) -> record -> record Source #

Update the record given an update function for the part.

The default implementation searches for some value of the type part in record and updates that value using the supplied function. The default implementation typechecks iff there is a single subvalue of type part in record.

update :: forall path. (Generic record, SuccessfulSearch part record path) => (part -> part) -> record -> record Source #

Update the record given an update function for the part.

The default implementation searches for some value of the type part in record and updates that value using the supplied function. The default implementation typechecks iff there is a single subvalue of type part in record.

Instances
 Has record record Source # Each type allows projecting itself (and that is an id projection). Instance detailsDefined in Control.Monad.Reader.Has Methodsextract :: record -> record Source #update :: (record -> record) -> record -> record Source # SuccessfulSearch a (a0, a1) path => Has a (a0, a1) Source # Instance detailsDefined in Control.Monad.Reader.Has Methodsextract :: (a0, a1) -> a Source #update :: (a -> a) -> (a0, a1) -> (a0, a1) Source # SuccessfulSearch a (a0, a1, a2) path => Has a (a0, a1, a2) Source # Instance detailsDefined in Control.Monad.Reader.Has Methodsextract :: (a0, a1, a2) -> a Source #update :: (a -> a) -> (a0, a1, a2) -> (a0, a1, a2) Source # SuccessfulSearch a (a0, a1, a2, a3) path => Has a (a0, a1, a2, a3) Source # Instance detailsDefined in Control.Monad.Reader.Has Methodsextract :: (a0, a1, a2, a3) -> a Source #update :: (a -> a) -> (a0, a1, a2, a3) -> (a0, a1, a2, a3) Source # SuccessfulSearch a (a0, a1, a2, a3, a4) path => Has a (a0, a1, a2, a3, a4) Source # Instance detailsDefined in Control.Monad.Reader.Has Methodsextract :: (a0, a1, a2, a3, a4) -> a Source #update :: (a -> a) -> (a0, a1, a2, a3, a4) -> (a0, a1, a2, a3, a4) Source # SuccessfulSearch a (a0, a1, a2, a3, a4, a5) path => Has a (a0, a1, a2, a3, a4, a5) Source # Instance detailsDefined in Control.Monad.Reader.Has Methodsextract :: (a0, a1, a2, a3, a4, a5) -> a Source #update :: (a -> a) -> (a0, a1, a2, a3, a4, a5) -> (a0, a1, a2, a3, a4, a5) Source #

type SuccessfulSearch part record path = (Search part (Rep record) ~ Found path, GHas path part (Rep record)) Source #

Type alias representing that the search of part in record has been successful.

The path is used to guide the default generic implementation of Has.

guard :: Alternative f => Bool -> f () #

Conditional failure of Alternative computations. Defined by

guard True  = pure ()
guard False = empty


#### Examples

Expand

Common uses of guard include conditionally signaling an error in an error monad and conditionally rejecting the current choice in an Alternative-based parser.

As an example of signaling an error in the error monad Maybe, consider a safe division function safeDiv x y that returns Nothing when the denominator y is zero and Just (x div y) otherwise. For example:

>>> safeDiv 4 0
Nothing
>>> safeDiv 4 2
Just 2


A definition of safeDiv using guards, but not guard:

safeDiv :: Int -> Int -> Maybe Int
safeDiv x y | y /= 0    = Just (x div y)
| otherwise = Nothing


A definition of safeDiv using guard and Monad do-notation:

safeDiv :: Int -> Int -> Maybe Int
safeDiv x y = do
guard (y /= 0)
return (x div y)


join :: Monad m => m (m a) -> m a #

The join function is the conventional monad join operator. It is used to remove one level of monadic structure, projecting its bound argument into the outer level.

#### Examples

Expand

A common use of join is to run an IO computation returned from an STM transaction, since STM transactions can't perform IO directly. Recall that

atomically :: STM a -> IO a


is used to run STM transactions atomically. So, by specializing the types of atomically and join to

atomically :: STM (IO b) -> IO (IO b)
join       :: IO (IO b)  -> IO b


we can compose them as

join . atomically :: STM (IO b) -> IO b


to run an STM transaction and the IO action it returns.

class Applicative m => Monad (m :: Type -> Type) where #

The Monad class defines the basic operations over a monad, a concept from a branch of mathematics known as category theory. From the perspective of a Haskell programmer, however, it is best to think of a monad as an abstract datatype of actions. Haskell's do expressions provide a convenient syntax for writing monadic expressions.

Instances of Monad should satisfy the following laws:

• return a >>= k  =  k a
• m >>= return  =  m
• m >>= (\x -> k x >>= h)  =  (m >>= k) >>= h

Furthermore, the Monad and Applicative operations should relate as follows:

• pure = return
• (<*>) = ap

The above laws imply:

• fmap f xs  =  xs >>= return . f
• (>>) = (*>)

and that pure and (<*>) satisfy the applicative functor laws.

The instances of Monad for lists, Maybe and IO defined in the Prelude satisfy these laws.

Minimal complete definition

(>>=)

Methods

(>>=) :: m a -> (a -> m b) -> m b infixl 1 #

Sequentially compose two actions, passing any value produced by the first as an argument to the second.

(>>) :: m a -> m b -> m b infixl 1 #

Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such as the semicolon) in imperative languages.

return :: a -> m a #

Inject a value into the monadic type.

fail :: String -> m a #

Fail with a message. This operation is not part of the mathematical definition of a monad, but is invoked on pattern-match failure in a do expression.

As part of the MonadFail proposal (MFP), this function is moved to its own class MonadFail (see Control.Monad.Fail for more details). The definition here will be removed in a future release.

Instances

class Functor (f :: Type -> Type) where #

The Functor class is used for types that can be mapped over. Instances of Functor should satisfy the following laws:

fmap id  ==  id
fmap (f . g)  ==  fmap f . fmap g

The instances of Functor for lists, Maybe and IO satisfy these laws.

Methods

fmap :: (a -> b) -> f a -> f b #

Instances
 Functor [] Since: base-2.1 Instance detailsDefined in GHC.Base Methodsfmap :: (a -> b) -> [a] -> [b] #(<$) :: a -> [b] -> [a] # Since: base-2.1 Instance detailsDefined in GHC.Base Methodsfmap :: (a -> b) -> Maybe a -> Maybe b #(<$) :: a -> Maybe b -> Maybe a # Since: base-2.1 Instance detailsDefined in GHC.Base Methodsfmap :: (a -> b) -> IO a -> IO b #(<$) :: a -> IO b -> IO a # Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsfmap :: (a -> b) -> Par1 a -> Par1 b #(<$) :: a -> Par1 b -> Par1 a # Since: base-4.6.0.0 Instance detailsDefined in Control.Exception Methodsfmap :: (a -> b) -> Handler a -> Handler b #(<$) :: a -> Handler b -> Handler a # Since: base-4.11.0.0 Instance detailsDefined in Data.Ord Methodsfmap :: (a -> b) -> Down a -> Down b #(<$) :: a -> Down b -> Down a # Since: base-2.1 Instance detailsDefined in Text.ParserCombinators.ReadP Methodsfmap :: (a -> b) -> ReadP a -> ReadP b #(<$) :: a -> ReadP b -> ReadP a # Since: base-4.9.0.0 Instance detailsDefined in GHC.Base Methodsfmap :: (a -> b) -> NonEmpty a -> NonEmpty b #(<$) :: a -> NonEmpty b -> NonEmpty a # Since: base-4.8.0.0 Instance detailsDefined in Text.ParserCombinators.ReadP Methodsfmap :: (a -> b) -> P a -> P b #(<$) :: a -> P b -> P a # Since: base-3.0 Instance detailsDefined in Data.Either Methodsfmap :: (a0 -> b) -> Either a a0 -> Either a b #(<$) :: a0 -> Either a b -> Either a a0 # Functor (V1 :: Type -> Type) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsfmap :: (a -> b) -> V1 a -> V1 b #(<$) :: a -> V1 b -> V1 a # Functor (U1 :: Type -> Type) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsfmap :: (a -> b) -> U1 a -> U1 b #(<$) :: a -> U1 b -> U1 a # Functor ((,) a) Since: base-2.1 Instance detailsDefined in GHC.Base Methodsfmap :: (a0 -> b) -> (a, a0) -> (a, b) #(<$) :: a0 -> (a, b) -> (a, a0) # Functor (Proxy :: Type -> Type) Since: base-4.7.0.0 Instance detailsDefined in Data.Proxy Methodsfmap :: (a -> b) -> Proxy a -> Proxy b #(<$) :: a -> Proxy b -> Proxy a # Functor m => Functor (ListT m) Instance detailsDefined in Control.Monad.Trans.List Methodsfmap :: (a -> b) -> ListT m a -> ListT m b #(<$) :: a -> ListT m b -> ListT m a # Functor m => Functor (MaybeT m) Instance detailsDefined in Control.Monad.Trans.Maybe Methodsfmap :: (a -> b) -> MaybeT m a -> MaybeT m b #(<$) :: a -> MaybeT m b -> MaybeT m a # Functor f => Functor (Rec1 f) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsfmap :: (a -> b) -> Rec1 f a -> Rec1 f b #(<$) :: a -> Rec1 f b -> Rec1 f a # Functor (URec Char :: Type -> Type) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsfmap :: (a -> b) -> URec Char a -> URec Char b #(<$) :: a -> URec Char b -> URec Char a # Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsfmap :: (a -> b) -> URec Double a -> URec Double b #(<$) :: a -> URec Double b -> URec Double a # Functor (URec Float :: Type -> Type) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsfmap :: (a -> b) -> URec Float a -> URec Float b #(<$) :: a -> URec Float b -> URec Float a # Functor (URec Int :: Type -> Type) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsfmap :: (a -> b) -> URec Int a -> URec Int b #(<$) :: a -> URec Int b -> URec Int a # Functor (URec Word :: Type -> Type) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsfmap :: (a -> b) -> URec Word a -> URec Word b #(<$) :: a -> URec Word b -> URec Word a # Functor (URec (Ptr ()) :: Type -> Type) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsfmap :: (a -> b) -> URec (Ptr ()) a -> URec (Ptr ()) b #(<$) :: a -> URec (Ptr ()) b -> URec (Ptr ()) a # Functor m => Functor (IdentityT m) Instance detailsDefined in Control.Monad.Trans.Identity Methodsfmap :: (a -> b) -> IdentityT m a -> IdentityT m b #(<$) :: a -> IdentityT m b -> IdentityT m a # Functor m => Functor (ErrorT e m) Instance detailsDefined in Control.Monad.Trans.Error Methodsfmap :: (a -> b) -> ErrorT e m a -> ErrorT e m b #(<$) :: a -> ErrorT e m b -> ErrorT e m a # Functor m => Functor (ExceptT e m) Instance detailsDefined in Control.Monad.Trans.Except Methodsfmap :: (a -> b) -> ExceptT e m a -> ExceptT e m b #(<$) :: a -> ExceptT e m b -> ExceptT e m a # Functor m => Functor (StateT s m) Instance detailsDefined in Control.Monad.Trans.State.Lazy Methodsfmap :: (a -> b) -> StateT s m a -> StateT s m b #(<$) :: a -> StateT s m b -> StateT s m a # Functor m => Functor (StateT s m) Instance detailsDefined in Control.Monad.Trans.State.Strict Methodsfmap :: (a -> b) -> StateT s m a -> StateT s m b #(<$) :: a -> StateT s m b -> StateT s m a # Functor m => Functor (WriterT w m) Instance detailsDefined in Control.Monad.Trans.Writer.Lazy Methodsfmap :: (a -> b) -> WriterT w m a -> WriterT w m b #(<$) :: a -> WriterT w m b -> WriterT w m a # Functor m => Functor (WriterT w m) Instance detailsDefined in Control.Monad.Trans.Writer.Strict Methodsfmap :: (a -> b) -> WriterT w m a -> WriterT w m b #(<$) :: a -> WriterT w m b -> WriterT w m a # Functor ((->) r :: Type -> Type) Since: base-2.1 Instance detailsDefined in GHC.Base Methodsfmap :: (a -> b) -> (r -> a) -> r -> b #(<$) :: a -> (r -> b) -> r -> a # Functor (K1 i c :: Type -> Type) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsfmap :: (a -> b) -> K1 i c a -> K1 i c b #(<$) :: a -> K1 i c b -> K1 i c a # (Functor f, Functor g) => Functor (f :+: g) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsfmap :: (a -> b) -> (f :+: g) a -> (f :+: g) b #(<$) :: a -> (f :+: g) b -> (f :+: g) a # (Functor f, Functor g) => Functor (f :*: g) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsfmap :: (a -> b) -> (f :*: g) a -> (f :*: g) b #(<$) :: a -> (f :*: g) b -> (f :*: g) a # Functor (ContT r m) Instance detailsDefined in Control.Monad.Trans.Cont Methodsfmap :: (a -> b) -> ContT r m a -> ContT r m b #(<$) :: a -> ContT r m b -> ContT r m a # Functor m => Functor (ReaderT r m) Instance detailsDefined in Control.Monad.Trans.Reader Methodsfmap :: (a -> b) -> ReaderT r m a -> ReaderT r m b #(<$) :: a -> ReaderT r m b -> ReaderT r m a # Functor f => Functor (M1 i c f) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsfmap :: (a -> b) -> M1 i c f a -> M1 i c f b #(<$) :: a -> M1 i c f b -> M1 i c f a # (Functor f, Functor g) => Functor (f :.: g) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsfmap :: (a -> b) -> (f :.: g) a -> (f :.: g) b #(<$) :: a -> (f :.: g) b -> (f :.: g) a # Functor m => Functor (RWST r w s m) Instance detailsDefined in Control.Monad.Trans.RWS.Lazy Methodsfmap :: (a -> b) -> RWST r w s m a -> RWST r w s m b #(<$) :: a -> RWST r w s m b -> RWST r w s m a # Functor m => Functor (RWST r w s m) Instance detailsDefined in Control.Monad.Trans.RWS.Strict Methodsfmap :: (a -> b) -> RWST r w s m a -> RWST r w s m b #(<$) :: a -> RWST r w s m b -> RWST r w s m a #

class Monad m => MonadFix (m :: Type -> Type) where #

Monads having fixed points with a 'knot-tying' semantics. Instances of MonadFix should satisfy the following laws:

purity
mfix (return . h) = return (fix h)
left shrinking (or tightening)
mfix (\x -> a >>= \y -> f x y) = a >>= \y -> mfix (\x -> f x y)
sliding
mfix (liftM h . f) = liftM h (mfix (f . h)), for strict h.
nesting
mfix (\x -> mfix (\y -> f x y)) = mfix (\x -> f x x)

This class is used in the translation of the recursive do notation supported by GHC and Hugs.

Methods

mfix :: (a -> m a) -> m a #

The fixed point of a monadic computation. mfix f executes the action f only once, with the eventual output fed back as the input. Hence f should not be strict, for then mfix f would diverge.

Instances

mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b) #

Map each element of a structure to a monadic action, evaluate these actions from left to right, and collect the results. For a version that ignores the results see mapM_.

sequence :: (Traversable t, Monad m) => t (m a) -> m (t a) #

Evaluate each monadic action in the structure from left to right, and collect the results. For a version that ignores the results see sequence_.

class Monad m => MonadIO (m :: Type -> Type) where #

Monads in which IO computations may be embedded. Any monad built by applying a sequence of monad transformers to the IO monad will be an instance of this class.

Instances should satisfy the following laws, which state that liftIO is a transformer of monads:

• liftIO . return = return
• liftIO (m >>= f) = liftIO m >>= (liftIO . f)

Methods

liftIO :: IO a -> m a #

Lift a computation from the IO monad.

Instances

mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a #

Direct MonadPlus equivalent of filter.

#### Examples

Expand

The filter function is just mfilter specialized to the list monad:

filter = ( mfilter :: (a -> Bool) -> [a] -> [a] )


An example using mfilter with the Maybe monad:

>>> mfilter odd (Just 1)
Just 1
>>> mfilter odd (Just 2)
Nothing


(<$!>) :: Monad m => (a -> b) -> m a -> m b infixl 4 # Strict version of <$>.

Since: base-4.8.0.0

unless :: Applicative f => Bool -> f () -> f () #

The reverse of when.

replicateM_ :: Applicative m => Int -> m a -> m () #

Like replicateM, but discards the result.

replicateM :: Applicative m => Int -> m a -> m [a] #

replicateM n act performs the action n times, gathering the results.

foldM_ :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m () #

Like foldM, but discards the result.

foldM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b #

The foldM function is analogous to foldl, except that its result is encapsulated in a monad. Note that foldM works from left-to-right over the list arguments. This could be an issue where (>>) and the folded function' are not commutative.

foldM f a1 [x1, x2, ..., xm]

==

do
a2 <- f a1 x1
a3 <- f a2 x2
...
f am xm

If right-to-left evaluation is required, the input list should be reversed.

Note: foldM is the same as foldlM

zipWithM_ :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m () #

zipWithM_ is the extension of zipWithM which ignores the final result.

zipWithM :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m [c] #

The zipWithM function generalizes zipWith to arbitrary applicative functors.

mapAndUnzipM :: Applicative m => (a -> m (b, c)) -> [a] -> m ([b], [c]) #

The mapAndUnzipM function maps its first argument over a list, returning the result as a pair of lists. This function is mainly used with complicated data structures or a state-transforming monad.

forever :: Applicative f => f a -> f b #

Repeat an action indefinitely.

#### Examples

Expand

A common use of forever is to process input from network sockets, Handles, and channels (e.g. MVar and Chan).

For example, here is how we might implement an echo server, using forever both to listen for client connections on a network socket and to echo client input on client connection handles:

echoServer :: Socket -> IO ()
echoServer socket = forever $do client <- accept socket forkFinally (echo client) (\_ -> hClose client) where echo :: Handle -> IO () echo client = forever$
hGetLine client >>= hPutStrLn client


(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c infixr 1 #

Right-to-left composition of Kleisli arrows. (>=>), with the arguments flipped.

Note how this operator resembles function composition (.):

(.)   ::            (b ->   c) -> (a ->   b) -> a ->   c
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c

(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c infixr 1 #

Left-to-right composition of Kleisli arrows.

filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a] #

This generalizes the list-based filter function.

forM :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b) #

forM is mapM with its arguments flipped. For a version that ignores the results see forM_.

msum :: (Foldable t, MonadPlus m) => t (m a) -> m a #

The sum of a collection of actions, generalizing concat. As of base 4.8.0.0, msum is just asum, specialized to MonadPlus.

sequence_ :: (Foldable t, Monad m) => t (m a) -> m () #

Evaluate each monadic action in the structure from left to right, and ignore the results. For a version that doesn't ignore the results see sequence.

As of base 4.8.0.0, sequence_ is just sequenceA_, specialized to Monad.

forM_ :: (Foldable t, Monad m) => t a -> (a -> m b) -> m () #

forM_ is mapM_ with its arguments flipped. For a version that doesn't ignore the results see forM.

As of base 4.8.0.0, forM_ is just for_, specialized to Monad.

mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m () #

Map each element of a structure to a monadic action, evaluate these actions from left to right, and ignore the results. For a version that doesn't ignore the results see mapM.

As of base 4.8.0.0, mapM_ is just traverse_, specialized to Monad.

fix :: (a -> a) -> a #

fix f is the least fixed point of the function f, i.e. the least defined x such that f x = x.

For example, we can write the factorial function using direct recursion as

>>> let fac n = if n <= 1 then 1 else n * fac (n-1) in fac 5
120


This uses the fact that Haskell’s let introduces recursive bindings. We can rewrite this definition using fix,

>>> fix (\rec n -> if n <= 1 then 1 else n * rec (n-1)) 5
120


Instead of making a recursive call, we introduce a dummy parameter rec; when used within fix, this parameter then refers to fix' argument, hence the recursion is reintroduced.

void :: Functor f => f a -> f () #

void value discards or ignores the result of evaluation, such as the return value of an IO action.

#### Examples

Expand

Replace the contents of a Maybe Int with unit:

>>> void Nothing
Nothing
>>> void (Just 3)
Just ()


Replace the contents of an Either Int Int with unit, resulting in an Either Int '()':

>>> void (Left 8675309)
Left 8675309
>>> void (Right 8675309)
Right ()


Replace every element of a list with unit:

>>> void [1,2,3]
[(),(),()]


Replace the second element of a pair with unit:

>>> void (1,2)
(1,())


Discard the result of an IO action:

>>> mapM print [1,2]
1
2
[(),()]
>>> void $mapM print [1,2] 1 2  ap :: Monad m => m (a -> b) -> m a -> m b # In many situations, the liftM operations can be replaced by uses of ap, which promotes function application. return f ap x1 ap ... ap xn is equivalent to liftMn f x1 x2 ... xn liftM5 :: Monad m => (a1 -> a2 -> a3 -> a4 -> a5 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r # Promote a function to a monad, scanning the monadic arguments from left to right (cf. liftM2). liftM4 :: Monad m => (a1 -> a2 -> a3 -> a4 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m r # Promote a function to a monad, scanning the monadic arguments from left to right (cf. liftM2). liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r # Promote a function to a monad, scanning the monadic arguments from left to right (cf. liftM2). liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r # Promote a function to a monad, scanning the monadic arguments from left to right. For example, liftM2 (+) [0,1] [0,2] = [0,2,1,3] liftM2 (+) (Just 1) Nothing = Nothing liftM :: Monad m => (a1 -> r) -> m a1 -> m r # Promote a function to a monad. when :: Applicative f => Bool -> f () -> f () # Conditional execution of Applicative expressions. For example, when debug (putStrLn "Debugging") will output the string Debugging if the Boolean value debug is True, and otherwise do nothing. (=<<) :: Monad m => (a -> m b) -> m a -> m b infixr 1 # Same as >>=, but with the arguments interchanged. class (Alternative m, Monad m) => MonadPlus (m :: Type -> Type) where # Monads that also support choice and failure. Minimal complete definition Nothing Methods mzero :: m a # The identity of mplus. It should also satisfy the equations mzero >>= f = mzero v >> mzero = mzero The default definition is mzero = empty  mplus :: m a -> m a -> m a # An associative operation. The default definition is mplus = (<|>)  Instances  Since: base-2.1 Instance detailsDefined in GHC.Base Methodsmzero :: [a] #mplus :: [a] -> [a] -> [a] # Since: base-2.1 Instance detailsDefined in GHC.Base Methodsmzero :: Maybe a #mplus :: Maybe a -> Maybe a -> Maybe a # Since: base-4.9.0.0 Instance detailsDefined in GHC.Base Methodsmzero :: IO a #mplus :: IO a -> IO a -> IO a # Since: base-2.1 Instance detailsDefined in Text.ParserCombinators.ReadP Methodsmzero :: ReadP a #mplus :: ReadP a -> ReadP a -> ReadP a # Since: base-2.1 Instance detailsDefined in Text.ParserCombinators.ReadP Methodsmzero :: P a #mplus :: P a -> P a -> P a # MonadPlus (U1 :: Type -> Type) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsmzero :: U1 a #mplus :: U1 a -> U1 a -> U1 a # MonadPlus (Proxy :: Type -> Type) Since: base-4.9.0.0 Instance detailsDefined in Data.Proxy Methodsmzero :: Proxy a #mplus :: Proxy a -> Proxy a -> Proxy a # Monad m => MonadPlus (ListT m) Instance detailsDefined in Control.Monad.Trans.List Methodsmzero :: ListT m a #mplus :: ListT m a -> ListT m a -> ListT m a # Monad m => MonadPlus (MaybeT m) Instance detailsDefined in Control.Monad.Trans.Maybe Methodsmzero :: MaybeT m a #mplus :: MaybeT m a -> MaybeT m a -> MaybeT m a # MonadPlus f => MonadPlus (Rec1 f) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsmzero :: Rec1 f a #mplus :: Rec1 f a -> Rec1 f a -> Rec1 f a # MonadPlus m => MonadPlus (IdentityT m) Instance detailsDefined in Control.Monad.Trans.Identity Methodsmzero :: IdentityT m a #mplus :: IdentityT m a -> IdentityT m a -> IdentityT m a # (Monad m, Error e) => MonadPlus (ErrorT e m) Instance detailsDefined in Control.Monad.Trans.Error Methodsmzero :: ErrorT e m a #mplus :: ErrorT e m a -> ErrorT e m a -> ErrorT e m a # (Monad m, Monoid e) => MonadPlus (ExceptT e m) Instance detailsDefined in Control.Monad.Trans.Except Methodsmzero :: ExceptT e m a #mplus :: ExceptT e m a -> ExceptT e m a -> ExceptT e m a # MonadPlus m => MonadPlus (StateT s m) Instance detailsDefined in Control.Monad.Trans.State.Lazy Methodsmzero :: StateT s m a #mplus :: StateT s m a -> StateT s m a -> StateT s m a # MonadPlus m => MonadPlus (StateT s m) Instance detailsDefined in Control.Monad.Trans.State.Strict Methodsmzero :: StateT s m a #mplus :: StateT s m a -> StateT s m a -> StateT s m a # (Monoid w, MonadPlus m) => MonadPlus (WriterT w m) Instance detailsDefined in Control.Monad.Trans.Writer.Lazy Methodsmzero :: WriterT w m a #mplus :: WriterT w m a -> WriterT w m a -> WriterT w m a # (Monoid w, MonadPlus m) => MonadPlus (WriterT w m) Instance detailsDefined in Control.Monad.Trans.Writer.Strict Methodsmzero :: WriterT w m a #mplus :: WriterT w m a -> WriterT w m a -> WriterT w m a # (MonadPlus f, MonadPlus g) => MonadPlus (f :*: g) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsmzero :: (f :*: g) a #mplus :: (f :*: g) a -> (f :*: g) a -> (f :*: g) a # MonadPlus m => MonadPlus (ReaderT r m) Instance detailsDefined in Control.Monad.Trans.Reader Methodsmzero :: ReaderT r m a #mplus :: ReaderT r m a -> ReaderT r m a -> ReaderT r m a # MonadPlus f => MonadPlus (M1 i c f) Since: base-4.9.0.0 Instance detailsDefined in GHC.Generics Methodsmzero :: M1 i c f a #mplus :: M1 i c f a -> M1 i c f a -> M1 i c f a # (Monoid w, MonadPlus m) => MonadPlus (RWST r w s m) Instance detailsDefined in Control.Monad.Trans.RWS.Lazy Methodsmzero :: RWST r w s m a #mplus :: RWST r w s m a -> RWST r w s m a -> RWST r w s m a # (Monoid w, MonadPlus m) => MonadPlus (RWST r w s m) Instance detailsDefined in Control.Monad.Trans.RWS.Strict Methodsmzero :: RWST r w s m a #mplus :: RWST r w s m a -> RWST r w s m a -> RWST r w s m a # class MonadTrans (t :: (Type -> Type) -> Type -> Type) where # The class of monad transformers. Instances should satisfy the following laws, which state that lift is a monad transformation: • lift . return = return • lift (m >>= f) = lift m >>= (lift . f) Methods lift :: Monad m => m a -> t m a # Lift a computation from the argument monad to the constructed monad. Instances  Instance detailsDefined in Control.Monad.Trans.List Methodslift :: Monad m => m a -> ListT m a # Instance detailsDefined in Control.Monad.Trans.Maybe Methodslift :: Monad m => m a -> MaybeT m a # MonadTrans (IdentityT :: (Type -> Type) -> Type -> Type) Instance detailsDefined in Control.Monad.Trans.Identity Methodslift :: Monad m => m a -> IdentityT m a # Instance detailsDefined in Control.Monad.Trans.Error Methodslift :: Monad m => m a -> ErrorT e m a # Instance detailsDefined in Control.Monad.Trans.Except Methodslift :: Monad m => m a -> ExceptT e m a # Instance detailsDefined in Control.Monad.Trans.State.Lazy Methodslift :: Monad m => m a -> StateT s m a # Instance detailsDefined in Control.Monad.Trans.State.Strict Methodslift :: Monad m => m a -> StateT s m a # Monoid w => MonadTrans (WriterT w) Instance detailsDefined in Control.Monad.Trans.Writer.Lazy Methodslift :: Monad m => m a -> WriterT w m a # Monoid w => MonadTrans (WriterT w) Instance detailsDefined in Control.Monad.Trans.Writer.Strict Methodslift :: Monad m => m a -> WriterT w m a # Instance detailsDefined in Control.Monad.Trans.Cont Methodslift :: Monad m => m a -> ContT r m a # MonadTrans (ReaderT r :: (Type -> Type) -> Type -> Type) Instance detailsDefined in Control.Monad.Trans.Reader Methodslift :: Monad m => m a -> ReaderT r m a # Monoid w => MonadTrans (RWST r w s) Instance detailsDefined in Control.Monad.Trans.RWS.Lazy Methodslift :: Monad m => m a -> RWST r w s m a # Monoid w => MonadTrans (RWST r w s) Instance detailsDefined in Control.Monad.Trans.RWS.Strict Methodslift :: Monad m => m a -> RWST r w s m a # class Monad m => MonadReader r (m :: Type -> Type) | m -> r where # See examples in Control.Monad.Reader. Note, the partially applied function type (->) r is a simple reader monad. See the instance declaration below. Methods Arguments  :: (r -> r) The function to modify the environment. -> m a Reader to run in the modified environment. -> m a Executes a computation in a modified environment. Instances  MonadReader r m => MonadReader r (MaybeT m) Instance detailsDefined in Control.Monad.Reader.Class Methodsask :: MaybeT m r #local :: (r -> r) -> MaybeT m a -> MaybeT m a #reader :: (r -> a) -> MaybeT m a # MonadReader r m => MonadReader r (ListT m) Instance detailsDefined in Control.Monad.Reader.Class Methodsask :: ListT m r #local :: (r -> r) -> ListT m a -> ListT m a #reader :: (r -> a) -> ListT m a # (Monoid w, MonadReader r m) => MonadReader r (WriterT w m) Instance detailsDefined in Control.Monad.Reader.Class Methodsask :: WriterT w m r #local :: (r -> r) -> WriterT w m a -> WriterT w m a #reader :: (r -> a) -> WriterT w m a # (Monoid w, MonadReader r m) => MonadReader r (WriterT w m) Instance detailsDefined in Control.Monad.Reader.Class Methodsask :: WriterT w m r #local :: (r -> r) -> WriterT w m a -> WriterT w m a #reader :: (r -> a) -> WriterT w m a # MonadReader r m => MonadReader r (StateT s m) Instance detailsDefined in Control.Monad.Reader.Class Methodsask :: StateT s m r #local :: (r -> r) -> StateT s m a -> StateT s m a #reader :: (r -> a) -> StateT s m a # MonadReader r m => MonadReader r (StateT s m) Instance detailsDefined in Control.Monad.Reader.Class Methodsask :: StateT s m r #local :: (r -> r) -> StateT s m a -> StateT s m a #reader :: (r -> a) -> StateT s m a # MonadReader r m => MonadReader r (IdentityT m) Instance detailsDefined in Control.Monad.Reader.Class Methodsask :: IdentityT m r #local :: (r -> r) -> IdentityT m a -> IdentityT m a #reader :: (r -> a) -> IdentityT m a # MonadReader r m => MonadReader r (ExceptT e m) Since: mtl-2.2 Instance detailsDefined in Control.Monad.Reader.Class Methodsask :: ExceptT e m r #local :: (r -> r) -> ExceptT e m a -> ExceptT e m a #reader :: (r -> a) -> ExceptT e m a # (Error e, MonadReader r m) => MonadReader r (ErrorT e m) Instance detailsDefined in Control.Monad.Reader.Class Methodsask :: ErrorT e m r #local :: (r -> r) -> ErrorT e m a -> ErrorT e m a #reader :: (r -> a) -> ErrorT e m a # Monad m => MonadReader r (ReaderT r m) Instance detailsDefined in Control.Monad.Reader.Class Methodsask :: ReaderT r m r #local :: (r -> r) -> ReaderT r m a -> ReaderT r m a #reader :: (r -> a) -> ReaderT r m a # MonadReader r ((->) r :: Type -> Type) Instance detailsDefined in Control.Monad.Reader.Class Methodsask :: r -> r #local :: (r -> r) -> (r -> a) -> r -> a #reader :: (r -> a) -> r -> a # MonadReader r' m => MonadReader r' (ContT r m) Instance detailsDefined in Control.Monad.Reader.Class Methodsask :: ContT r m r' #local :: (r' -> r') -> ContT r m a -> ContT r m a #reader :: (r' -> a) -> ContT r m a # (Monad m, Monoid w) => MonadReader r (RWST r w s m) Instance detailsDefined in Control.Monad.Reader.Class Methodsask :: RWST r w s m r #local :: (r -> r) -> RWST r w s m a -> RWST r w s m a #reader :: (r -> a) -> RWST r w s m a # (Monad m, Monoid w) => MonadReader r (RWST r w s m) Instance detailsDefined in Control.Monad.Reader.Class Methodsask :: RWST r w s m r #local :: (r -> r) -> RWST r w s m a -> RWST r w s m a #reader :: (r -> a) -> RWST r w s m a # newtype ReaderT r (m :: k -> Type) (a :: k) :: forall k. Type -> (k -> Type) -> k -> Type # The reader monad transformer, which adds a read-only environment to the given monad. The return function ignores the environment, while >>= passes the inherited environment to both subcomputations. Constructors  ReaderT FieldsrunReaderT :: r -> m a Instances  Monad m => MonadReader r (ReaderT r m) Instance detailsDefined in Control.Monad.Reader.Class Methodsask :: ReaderT r m r #local :: (r -> r) -> ReaderT r m a -> ReaderT r m a #reader :: (r -> a) -> ReaderT r m a # MonadError e m => MonadError e (ReaderT r m) Instance detailsDefined in Control.Monad.Error.Class MethodsthrowError :: e -> ReaderT r m a #catchError :: ReaderT r m a -> (e -> ReaderT r m a) -> ReaderT r m a # MonadTrans (ReaderT r :: (Type -> Type) -> Type -> Type) Instance detailsDefined in Control.Monad.Trans.Reader Methodslift :: Monad m => m a -> ReaderT r m a # Monad m => Monad (ReaderT r m) Instance detailsDefined in Control.Monad.Trans.Reader Methods(>>=) :: ReaderT r m a -> (a -> ReaderT r m b) -> ReaderT r m b #(>>) :: ReaderT r m a -> ReaderT r m b -> ReaderT r m b #return :: a -> ReaderT r m a #fail :: String -> ReaderT r m a # Functor m => Functor (ReaderT r m) Instance detailsDefined in Control.Monad.Trans.Reader Methodsfmap :: (a -> b) -> ReaderT r m a -> ReaderT r m b #(<$) :: a -> ReaderT r m b -> ReaderT r m a # MonadFix m => MonadFix (ReaderT r m) Instance detailsDefined in Control.Monad.Trans.Reader Methodsmfix :: (a -> ReaderT r m a) -> ReaderT r m a # MonadFail m => MonadFail (ReaderT r m) Instance detailsDefined in Control.Monad.Trans.Reader Methodsfail :: String -> ReaderT r m a # Applicative m => Applicative (ReaderT r m) Instance detailsDefined in Control.Monad.Trans.Reader Methodspure :: a -> ReaderT r m a #(<*>) :: ReaderT r m (a -> b) -> ReaderT r m a -> ReaderT r m b #liftA2 :: (a -> b -> c) -> ReaderT r m a -> ReaderT r m b -> ReaderT r m c #(*>) :: ReaderT r m a -> ReaderT r m b -> ReaderT r m b #(<*) :: ReaderT r m a -> ReaderT r m b -> ReaderT r m a # Contravariant m => Contravariant (ReaderT r m) Instance detailsDefined in Control.Monad.Trans.Reader Methodscontramap :: (a -> b) -> ReaderT r m b -> ReaderT r m a #(>\$) :: b -> ReaderT r m b -> ReaderT r m a # MonadZip m => MonadZip (ReaderT r m) Instance detailsDefined in Control.Monad.Trans.Reader Methodsmzip :: ReaderT r m a -> ReaderT r m b -> ReaderT r m (a, b) #mzipWith :: (a -> b -> c) -> ReaderT r m a -> ReaderT r m b -> ReaderT r m c #munzip :: ReaderT r m (a, b) -> (ReaderT r m a, ReaderT r m b) # MonadIO m => MonadIO (ReaderT r m) Instance detailsDefined in Control.Monad.Trans.Reader MethodsliftIO :: IO a -> ReaderT r m a # Alternative m => Alternative (ReaderT r m) Instance detailsDefined in Control.Monad.Trans.Reader Methodsempty :: ReaderT r m a #(<|>) :: ReaderT r m a -> ReaderT r m a -> ReaderT r m a #some :: ReaderT r m a -> ReaderT r m [a] #many :: ReaderT r m a -> ReaderT r m [a] # MonadPlus m => MonadPlus (ReaderT r m) Instance detailsDefined in Control.Monad.Trans.Reader Methodsmzero :: ReaderT r m a #mplus :: ReaderT r m a -> ReaderT r m a -> ReaderT r m a #

Computations are functions of a shared environment.

The return function ignores the environment, while >>= passes the inherited environment to both subcomputations.

Arguments

 :: Reader r a A Reader to run. -> r An initial environment. -> a

Runs a Reader and extracts the final value from it. (The inverse of reader.)

Transform the value returned by a Reader.

• runReader (mapReader f m) = f . runReader m

Arguments

 :: (r' -> r) The function to modify the environment. -> Reader r a Computation to run in the modified environment. -> Reader r' a

Execute a computation in a modified environment (a specialization of withReaderT).

• runReader (withReader f m) = runReader m . f

mapReaderT :: (m a -> n b) -> ReaderT r m a -> ReaderT r n b #

Transform the computation inside a ReaderT.

• runReaderT (mapReaderT f m) = f . runReaderT m

Arguments

 :: (r' -> r) The function to modify the environment. -> ReaderT r m a Computation to run in the modified environment. -> ReaderT r' m a

Execute a computation in a modified environment (a more general version of local).

• runReaderT (withReaderT f m) = runReaderT m . f

Retrieves the part of the monad environment.

This is Control.Monad.Reader's ask with the type adjusted for better compatibility with Has.

asks :: (MonadReader record m, Has part record) => (part -> a) -> m a Source #

Retrieves a function of the part of the current environment.

This is Control.Monad.Reader's asks with the type adjusted for better compatibility with Has.

reader :: (MonadReader record m, Has part record) => (part -> a) -> m a Source #

Retrieves a function of the part of the current environment.

This is Control.Monad.Reader's reader with the type adjusted for better compatibility with Has`.