Could you show a simple code example which would display the useful application of Data.Functor
's Product
and Coproduct
?
A Product
of a Const
and a Reader
can be used to easily implement two-stage evaluation. For example, suppose you need to use some monadic effect between the two phases, but you want to make sure that your client code cannot do that (because you want to finely control how and when it happens):
type TwoPhase c r = Product (Const c) (Reader r)
run :: (Monad m, Monoid c) => (c -> m r) -> TwoPhase c r a -> m a
run prepare (Pair (Const deps, phase2)) = do
r <- prepare deps
return $ runReader phase2 r
Note that this of course only permits an Applicative
interface for your API, not a monadic one; but that's what you usually want anyway in a situation like this.