{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {- | Module : Data.SemiIsoFunctor.Wrapped Description : SemiIso instances for wrapped monads. Copyright : (c) Paweł Nowak License : MIT Maintainer : Paweł Nowak Stability : experimental Every monad (with fail) is a SemiIsoMonad. -} module Data.SemiIsoFunctor.Wrapped where import Control.Applicative import Control.Lens.SemiIso import Control.Monad import Data.SemiIsoFunctor -- | A wrapped covariant functor. 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))