packages feed

mmzk-env-0.6.0.0: src/Data/Env/Internal/Validation.hs

{- |
Module      : Data.Env.Internal.Validation
Description : Internal applicative for error accumulation

Like 'Either', but the 'Applicative' instance accumulates failures using
the 'Semigroup' on @e@ instead of short-circuiting. Used by the generic
record parsers to report every invalid field in one pass.

INTERNAL — not exported from the library API.
-}
module Data.Env.Internal.Validation (
  Validation (..),
  validationToEither,
) where

-- | Like 'Either', but the 'Applicative' instance accumulates failures using
-- the 'Semigroup' on @e@ instead of short-circuiting.
data Validation e a = VFailure e | VSuccess a
  deriving (Show, Eq)

instance Functor (Validation e) where
  fmap _ (VFailure e) = VFailure e
  fmap f (VSuccess a) = VSuccess (f a)

instance Semigroup e => Applicative (Validation e) where
  pure = VSuccess
  VSuccess f  <*> VSuccess x  = VSuccess (f x)
  VFailure e1 <*> VFailure e2 = VFailure (e1 <> e2)
  VFailure e  <*> _           = VFailure e
  _           <*> VFailure e  = VFailure e

validationToEither :: Validation e a -> Either e a
validationToEither (VSuccess a) = Right a
validationToEither (VFailure e) = Left e