module Data.Variation
(
Variation(..)
, nominal, variations
) where
import Control.DeepSeq
import Data.Functor.Apply
import Data.Functor.Bind
import Data.Functor.Classes
import Data.Monoid1
import Data.Semigroup
import Data.Serialize (Serialize)
import GHC.Generics
data Variation f a =
Variation
{ _nominal :: !a
, _variations :: !(f a)
} deriving (Generic, Functor, Foldable, Traversable)
nominal :: Functor f => (a -> f a) -> Variation t a -> f (Variation t a)
nominal f (Variation n v) = flip Variation v <$> f n
variations :: Functor f => (t a -> f (t a)) -> Variation t a -> f (Variation t a)
variations f (Variation n v) = Variation n <$> f v
instance (NFData a, NFData (f a)) => NFData (Variation f a)
instance (Serialize a, Serialize (f a)) => Serialize (Variation f a) where
instance (Apply f, Monoid1 f) => Applicative (Variation f) where
pure = flip Variation empty1
Variation f fs <*> Variation x xs =
Variation
(f x)
((fs <.> xs) `append1` (f <$> xs) `append1` (($ x) <$> fs))
joinV :: (Bind f, Monoid1 f) => Variation f (Variation f a) -> Variation f a
joinV (Variation (Variation nn nv) v) =
let vv = _variations <$> v
vn = _nominal <$> v
in Variation nn $ join vv `append1` vn `append1` nv
instance (Bind f, Monoid1 f) => Monad (Variation f) where
return = pure
p >>= f = joinV $ f <$> p
instance Append1 f => Append1 (Variation f) where
Variation x xs `append1` Variation _ ys = Variation x (xs `append1` ys)
instance Append1 f => Semigroup (Variation f a) where
(<>) = append1
instance (Monoid a, Monoid1 f) => Monoid (Variation f a) where
mempty = Variation mempty empty1
mappend = (<>)
instance Show1 f => Show1 (Variation f) where
liftShowsPrec f g n (Variation x xs) =
showsBinaryWith f (liftShowsPrec f g) "Variation" n x xs
instance (Show1 f, Show a) => Show (Variation f a) where
showsPrec = showsPrec1