module Data.Valid where import Data.Bifoldable import Data.Bifunctor import Data.Bitraversable import Data.Functor.Classes import Util (compose2) data Valid e a = Failure e | Valid a deriving (Eq, Read, Show, Functor, Foldable, Traversable) instance Semigroup e => Applicative (Valid e) where pure = Valid Failure x <*> Failure y = Failure (x <> y) Failure x <*> Valid _ = Failure x Valid _ <*> Failure y = Failure y Valid f <*> Valid x = Valid (f x) instance Bifunctor Valid where bimap = bimapDefault instance Bifoldable Valid where bifoldMap = bifoldMapDefault instance Bitraversable Valid where bitraverse f g = fmap fromEither . bitraverse f g . toEither instance Eq2 Valid where liftEq2 f g = compose2 (liftEq2 f g) toEither toEither fromEither :: Either e a -> Valid e a fromEither = either Failure Valid toEither :: Valid e a -> Either e a toEither (Failure e) = Left e toEither (Valid a) = Right a