module Data.SemiIsoFunctor.Wrapped where
import Control.Applicative
import Control.Lens.SemiIso
import Control.Monad
import Data.SemiIsoFunctor
newtype WrappedCovariant m a = WrappedCovariant { runCovariant :: m a }
deriving (Functor, Applicative, Alternative, Monad)
instance Monad m => SemiIsoFunctor (WrappedCovariant m) where
simapCo ai m = m >>= either fail return . apply ai
instance Monad m => SemiIsoApply (WrappedCovariant m) where
sipure ai = either fail return (unapply ai ())
f /*/ g = liftM2 (,) f g
instance (Monad m, Alternative m) => SemiIsoAlternative (WrappedCovariant m) where
siempty = empty
f /|/ g = f <|> g
instance Monad m => SemiIsoMonad (WrappedCovariant m) where
f //= g = f >>= (\x -> g x >>= \y -> return (x, y))