-- |-- Module : Control.Applicative.Lift-- Copyright : (c) Ross Paterson 2010-- License : BSD-style (see the file LICENSE)---- Maintainer : ross@soi.city.ac.uk-- Stability : experimental-- Portability : portable---- Adding a new kind of pure computation to an applicative functor.
module Control.Applicative.Lift (
Lift(..), unLift,
-- * Collecting errors
Errors, failure
) where
import Control.Applicative
import Data.Foldable (Foldable(foldMap))
import Data.Functor.Constant
import Data.Monoid (Monoid(mappend))
import Data.Traversable (Traversable(traverse))
-- | Applicative functor formed by adding pure computations to a given-- applicative functor.
data Liftfa = Purea | Other (fa)
instance (Functor f) =>Functor (Liftf) where
fmapf (Purex) = Pure (fx)
fmapf (Othery) = Other (fmapfy)
instance (Foldable f) =>Foldable (Liftf) where
foldMapf (Purex) = fxfoldMapf (Othery) = foldMapfy
instance (Traversable f) =>Traversable (Liftf) where
traversef (Purex) = Pure<$>fxtraversef (Othery) = Other<$>traversefy-- | A combination is 'Pure' only if both parts are.
instance (Applicative f) =>Applicative (Liftf) where
pure = PurePuref<*>Purex = Pure (fx)
Puref<*>Othery = Other (f<$>y)
Otherf<*>Purex = Other (($x) <$>f)
Otherf<*>Othery = Other (f<*>y)
-- | A combination is 'Pure' only either part is.
instance Alternative f =>Alternative (Liftf) where
empty = OtheremptyPurex<|> _ = PurexOther _ <|>Purey = PureyOtherx<|>Othery = Other (x<|>y)
-- | Projection to the other functor.unLift :: Applicative f =>Liftfa -> faunLift (Purex) = purexunLift (Othere) = e-- | An applicative functor that collects a monoid (e.g. lists) of errors.-- A sequence of computations fails if any of its components do, but-- unlike monads made with 'ErrorT' from "Control.Monad.Trans.Error",-- these computations continue after an error, collecting all the errors.type Errors e = Lift (Constant e)-- | Report an error.failure :: Monoid e =>e -> Errorseafailuree = Other (Constante)