{-# LANGUAGE UndecidableInstances #-}
module Barbies.Internal.Containers
(
Container(..)
, ErrorContainer(..)
)
where
import Data.Functor.Barbie
import Data.Bifunctor (first)
import Data.Bitraversable (bitraverse)
import Data.Functor.Const
import GHC.Generics (Generic)
newtype Container b a
= Container { getContainer :: b (Const a) }
deriving (Generic)
deriving instance Eq (b (Const a)) => Eq (Container b a)
deriving instance Ord (b (Const a)) => Ord (Container b a)
deriving instance Read (b (Const a)) => Read (Container b a)
deriving instance Show (b (Const a)) => Show (Container b a)
instance FunctorB b => Functor (Container b) where
fmap f
= Container . (bmap (first f)) . getContainer
instance TraversableB b => Foldable (Container b) where
foldMap f
= bfoldMap (f . getConst) . getContainer
instance TraversableB b => Traversable (Container b) where
traverse f
= fmap Container . btraverse (bitraverse f pure) . getContainer
instance ApplicativeB b => Applicative (Container b) where
pure a
= Container $ bpure (Const a)
l <*> r
= Container $ bzipWith appConst (getContainer l) (getContainer r)
where
appConst :: Const (a -> a') x -> Const a x -> Const a' x
appConst (Const f) (Const a)
= Const (f a)
newtype ErrorContainer b e
= ErrorContainer { getErrorContainer :: b (Either e) }
deriving (Generic)
deriving instance Eq (b (Either e)) => Eq (ErrorContainer b e)
deriving instance Ord (b (Either e)) => Ord (ErrorContainer b e)
deriving instance Read (b (Either e)) => Read (ErrorContainer b e)
deriving instance Show (b (Either e)) => Show (ErrorContainer b e)
instance FunctorB b => Functor (ErrorContainer b) where
fmap f
= ErrorContainer . (bmap (first f)) . getErrorContainer
instance TraversableB b => Foldable (ErrorContainer b) where
foldMap f
= bfoldMap (either f (const mempty)) . getErrorContainer
instance TraversableB b => Traversable (ErrorContainer b) where
traverse f
= fmap ErrorContainer . btraverse (bitraverse f pure) . getErrorContainer