A Product of Const and a Reader can be used to easily implement a two-step evaluation. For example, suppose you need to use some kind of monadic effect between the two phases, but you want to make sure that your client code cannot do this (because you want to precisely control how and when this happens):
type TwoPhase cr = Product (Const c) (Reader a) run :: (Monad m, Monoid c) => (c -> mr) -> TwoPhase cra -> ma run prepare (Pair (Const deps, phase2)) = do r <- prepare deps return $ runReader r
Note that this, of course, enables the Applicative interface for your API, and not monodic; but what you usually want anyway in such a situation.
source share