{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
module Data.Monoid.Coproduct
( (:+:)
, inL, inR
, mappendL, mappendR
, killL, killR
, untangle
) where
import Data.Either (lefts, rights)
import Data.Semigroup
import Data.Typeable
import Data.Monoid.Action
newtype m :+: n = MCo { forall m n. (m :+: n) -> [Either m n]
unMCo :: [Either m n] }
deriving (Typeable, Int -> (m :+: n) -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall m n. (Show m, Show n) => Int -> (m :+: n) -> ShowS
forall m n. (Show m, Show n) => [m :+: n] -> ShowS
forall m n. (Show m, Show n) => (m :+: n) -> String
showList :: [m :+: n] -> ShowS
$cshowList :: forall m n. (Show m, Show n) => [m :+: n] -> ShowS
show :: (m :+: n) -> String
$cshow :: forall m n. (Show m, Show n) => (m :+: n) -> String
showsPrec :: Int -> (m :+: n) -> ShowS
$cshowsPrec :: forall m n. (Show m, Show n) => Int -> (m :+: n) -> ShowS
Show)
inL :: m -> m :+: n
inL :: forall m n. m -> m :+: n
inL m
m = forall m n. [Either m n] -> m :+: n
MCo [forall a b. a -> Either a b
Left m
m]
inR :: n -> m :+: n
inR :: forall n m. n -> m :+: n
inR n
n = forall m n. [Either m n] -> m :+: n
MCo [forall a b. b -> Either a b
Right n
n]
mappendL :: m -> m :+: n -> m :+: n
mappendL :: forall m n. m -> (m :+: n) -> m :+: n
mappendL = forall a. Monoid a => a -> a -> a
mappend forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall m n. m -> m :+: n
inL
mappendR :: n -> m :+: n -> m :+: n
mappendR :: forall n m. n -> (m :+: n) -> m :+: n
mappendR = forall a. Monoid a => a -> a -> a
mappend forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n m. n -> m :+: n
inR
instance Semigroup (m :+: n) where
(MCo [Either m n]
es1) <> :: (m :+: n) -> (m :+: n) -> m :+: n
<> (MCo [Either m n]
es2) = forall m n. [Either m n] -> m :+: n
MCo ([Either m n]
es1 forall a. [a] -> [a] -> [a]
++ [Either m n]
es2)
instance Monoid (m :+: n) where
mempty :: m :+: n
mempty = forall m n. [Either m n] -> m :+: n
MCo []
mappend :: (m :+: n) -> (m :+: n) -> m :+: n
mappend = forall a. Semigroup a => a -> a -> a
(<>)
killR :: Monoid m => m :+: n -> m
killR :: forall m n. Monoid m => (m :+: n) -> m
killR = forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. [Either a b] -> [a]
lefts forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall m n. (m :+: n) -> [Either m n]
unMCo
killL :: Monoid n => m :+: n -> n
killL :: forall n m. Monoid n => (m :+: n) -> n
killL = forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. [Either a b] -> [b]
rights forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall m n. (m :+: n) -> [Either m n]
unMCo
untangle :: (Action m n, Monoid m, Monoid n) => m :+: n -> (m,n)
untangle :: forall m n. (Action m n, Monoid m, Monoid n) => (m :+: n) -> (m, n)
untangle (MCo [Either m n]
elts) = forall {m} {b}.
(Monoid m, Monoid b, Action m b) =>
(m, b) -> [Either m b] -> (m, b)
untangle' forall a. Monoid a => a
mempty [Either m n]
elts
where untangle' :: (m, b) -> [Either m b] -> (m, b)
untangle' (m, b)
cur [] = (m, b)
cur
untangle' (m
curM, b
curN) (Left m
m : [Either m b]
elts') = (m, b) -> [Either m b] -> (m, b)
untangle' (m
curM forall a. Monoid a => a -> a -> a
`mappend` m
m, b
curN) [Either m b]
elts'
untangle' (m
curM, b
curN) (Right b
n : [Either m b]
elts') = (m, b) -> [Either m b] -> (m, b)
untangle' (m
curM, b
curN forall a. Monoid a => a -> a -> a
`mappend` forall m s. Action m s => m -> s -> s
act m
curM b
n) [Either m b]
elts'
instance (Action m r, Action n r) => Action (m :+: n) r where
act :: (m :+: n) -> r -> r
act = forall a. Endo a -> a -> a
appEndo forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall a. (a -> a) -> Endo a
Endo forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall m s. Action m s => m -> s -> s
act forall m s. Action m s => m -> s -> s
act) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall m n. (m :+: n) -> [Either m n]
unMCo