packages feed

pandora-0.5.5: Pandora/Paradigm/Primary/Functor/Validation.hs

module Pandora.Paradigm.Primary.Functor.Validation where

import Pandora.Core.Interpreted ((<~))
import Pandora.Pattern.Semigroupoid ((.))
import Pandora.Pattern.Category ((<--), (<---))
import Pandora.Pattern.Functor.Covariant (Covariant ((<-|-)))
import Pandora.Pattern.Functor.Semimonoidal (Semimonoidal (mult))
import Pandora.Pattern.Functor.Monoidal (Monoidal (unit))
import Pandora.Pattern.Functor.Traversable (Traversable ((<-/-)))
import Pandora.Pattern.Object.Setoid (Setoid ((==)))
import Pandora.Pattern.Object.Chain (Chain ((<=>)))
import Pandora.Pattern.Object.Semigroup (Semigroup ((+)))
import Pandora.Paradigm.Algebraic.Exponential (type (-->))
import Pandora.Paradigm.Algebraic.Product ((:*:) ((:*:)))
import Pandora.Paradigm.Algebraic.Sum ((:+:) (Option, Adoption))
import Pandora.Paradigm.Algebraic.One (One (One))
import Pandora.Paradigm.Algebraic (point)
import Pandora.Pattern.Morphism.Flip (Flip (Flip))
import Pandora.Pattern.Morphism.Straight (Straight (Straight))
import Pandora.Paradigm.Primary.Object.Boolean (Boolean (False))
import Pandora.Paradigm.Primary.Object.Ordering (Ordering (Less, Greater))

data Validation e a = Flaws e | Validated a

instance Covariant (->) (->) (Validation e) where
	_ <-|- Flaws e = Flaws e
	f <-|- Validated x = Validated <-- f x

instance Covariant (->) (->) (Flip Validation a) where
	f <-|- Flip (Flaws e) = Flip . Flaws <-- f e
	_ <-|- Flip (Validated x) = Flip <-- Validated x

instance Semigroup e => Semimonoidal (-->) (:*:) (:*:) (Validation e) where
	mult = Straight <-- \case
		Validated x :*: Validated y -> Validated <--- x :*: y
		Flaws x :*: Flaws y -> Flaws <-- x + y
		Validated _ :*: Flaws y -> Flaws y
		Flaws x :*: Validated _ -> Flaws x

instance Semigroup e => Monoidal (-->) (-->) (:*:) (:*:) (Validation e) where
	unit _ = Straight <-- Validated . (<~ One)

instance Semigroup e => Semimonoidal (-->) (:*:) (:+:) (Validation e) where
	mult = Straight <-- \case
		Flaws _ :*: y -> Adoption <-|- y
		Validated x :*: _ -> Option <-|- Validated x

instance Traversable (->) (->) (Validation e) where
	f <-/- Validated x = Validated <-|- f x
	_ <-/- Flaws e = point <-- Flaws e

instance (Setoid e, Setoid a) => Setoid (Validation e a) where
	Validated x == Validated y = x == y
	Flaws x == Flaws y = x == y
	_ == _ = False

instance (Chain e, Chain a) => Chain (Validation e a) where
	Validated x <=> Validated y = x <=> y
	Flaws x <=> Flaws y = x <=> y
	Flaws _ <=> Validated _ = Less
	Validated _ <=> Flaws _ = Greater

instance (Semigroup e, Semigroup a) => Semigroup (Validation e a) where
	Validated x + Validated y = Validated <-- x + y
	Flaws x + Flaws y = Flaws <-- x + y
	Flaws _ + Validated y = Validated y
	Validated x + Flaws _ = Validated x

validation :: (e -> r) -> (a -> r) -> Validation e a -> r
validation f _ (Flaws x) = f x
validation _ s (Validated x) = s x