module Data.Separated.Separated(
Separated
, separated
, Separated1
, separated1
, separated1Head
, separated1Tail
, empty
, (+-)
, single
, shift
, separatedSwap
, (.++.)
, (++.)
, (.++)
) where
import Control.Applicative(Applicative((<*>), pure))
import Control.Category(Category(id, (.)))
import Control.Lens.Iso(Iso, iso, from)
import Control.Lens.Tuple(_1, _2)
import Control.Lens.Type(Lens)
import Data.Functor(Functor(fmap))
import Data.Functor.Apply(Apply((<.>)))
import Data.Bifunctor(Bifunctor(bimap))
import Data.Eq(Eq)
import Data.List(intercalate, zipWith, repeat)
import Data.Monoid(Monoid(mappend, mempty))
import Data.Ord(Ord)
import Data.Semigroup(Semigroup((<>)))
import Data.Separated.SeparatedCons(SeparatedCons((+:), SeparatedConsF, SeparatedConsG))
import Data.String(String)
import Data.Tuple(uncurry)
import Prelude(Show(show))
import Control.Lens((^.), (#))
data Separated s a =
Separated [(s, a)]
deriving (Eq, Ord)
instance Bifunctor Separated where
bimap f g (Separated x) =
Separated (fmap (bimap f g) x)
instance Functor (Separated s) where
fmap =
bimap id
instance Semigroup s => Apply (Separated s) where
(<.>) =
separatedAp (<>)
instance Monoid s => Applicative (Separated s) where
(<*>) =
separatedAp mappend
pure =
Separated . repeat . (,) mempty
instance (Show s, Show a) => Show (Separated s a) where
show (Separated x) =
showSeparated id x
instance Semigroup (Separated s a) where
Separated x <> Separated y =
Separated (x <> y)
instance Monoid (Separated s a) where
mappend =
(<>)
mempty =
Separated mempty
instance SeparatedCons Separated1 Separated where
type SeparatedConsF Separated = Separated1
type SeparatedConsG Separated1 = Separated
s +: Separated1 a (Separated x) =
Separated ((s, a) : x)
separated ::
Iso [(s, a)] [(t, b)] (Separated s a) (Separated t b)
separated =
iso Separated (\(Separated x) -> x)
data Separated1 a s =
Separated1 a (Separated s a)
deriving (Eq, Ord)
instance Bifunctor Separated1 where
bimap f g (Separated1 a x) =
Separated1 (f a) (bimap g f x)
instance Functor (Separated1 s) where
fmap =
bimap id
instance Semigroup s => Apply (Separated1 s) where
(<.>) =
separated1Ap (<>)
instance (Show a, Show s) => Show (Separated1 a s) where
show (Separated1 a (Separated x)) =
showSeparated (show a:) x
instance Monoid s => Applicative (Separated1 s) where
(<*>) =
separated1Ap mappend
pure =
Separated1 mempty . swapSeparated . pure
separated1 ::
Iso (a, Separated s a) (b, Separated t b) (Separated1 a s) (Separated1 b t)
separated1 =
iso (uncurry Separated1) (\(Separated1 a x) -> (a, x))
instance SeparatedCons Separated Separated1 where
type SeparatedConsF Separated1 = Separated
type SeparatedConsG Separated = Separated1
(+:) =
Separated1
separated1Head ::
Lens (Separated1 a t) (Separated1 a t) a a
separated1Head =
from separated1 . _1
separated1Tail ::
Lens (Separated1 a s) (Separated1 a t) (Separated s a) (Separated t a)
separated1Tail =
from separated1 . _2
empty ::
Separated s a
empty =
Separated []
(+-) ::
s
-> a
-> Separated s a
s +- a =
s +: single a
single ::
a
-> Separated1 a s
single a =
Separated1 a empty
shift ::
Iso (Separated1 a s) (Separated1 b t) ([(a, s)], a) ([(b, t)], b)
shift =
let shiftR ([], a) =
Separated1 a (Separated [])
shiftR ((b, s):r, a) =
let Separated1 z' (Separated w) = shiftR (r, b)
in Separated1 z' (Separated ((s, a) : w))
shiftL (Separated1 s' (Separated [])) =
([], s')
shiftL (Separated1 s' (Separated ((a, t') : r))) =
let (w, z) = shiftL (Separated1 t' (Separated r))
in ((s', a) : w, z)
in iso shiftL shiftR
separatedSwap ::
Iso (Separated s a) (Separated t b) (Separated a s) (Separated b t)
separatedSwap =
let swap (a, b) = (b, a)
in iso (\(Separated x) -> Separated (fmap swap x)) (\(Separated x) -> Separated (fmap swap x))
(.++.) ::
Separated1 s a
-> Separated1 a s
-> Separated s a
Separated1 s x .++. Separated1 t (Separated y) =
let (q, r') = (s, x) ^. separated1 . shift
in Separated (q <> ((r', t) : y))
infixr 5 .++.
(++.) ::
Separated s a
-> Separated1 s a
-> Separated1 s a
Separated x ++. Separated1 t y =
let (z, w') = separated1 . shift # (x, t)
in Separated1 z (w' <> y)
infixr 5 ++.
(.++) ::
Separated1 a s
-> Separated s a
-> Separated1 a s
Separated1 a x .++ y =
Separated1 a (x <> y)
infixr 5 .++
showSeparated ::
(Show a, Show s, Functor f) =>
(f String -> [String])
-> f (s, a)
-> String
showSeparated f x =
'[' : intercalate "," (f (fmap (\(s, a) -> show s <> "," <> show a) x)) <> "]"
separatedAp ::
(s -> s -> s)
-> Separated s (a -> b)
-> Separated s a
-> Separated s b
separatedAp op (Separated f) (Separated a) =
Separated (zipWith (\(s, f') (t, a') -> (s `op` t, f' a')) f a)
separated1Ap ::
(a -> a -> a)
-> Separated1 a (s -> t)
-> Separated1 a s
-> Separated1 a t
separated1Ap op (Separated1 f (Separated fs)) (Separated1 a (Separated as)) =
Separated1 (f `op` a) (Separated (zipWith (\(s, f') (t, a') -> (s t, f' `op` a')) fs as))
swapSeparated ::
Separated s a
-> Separated a s
swapSeparated (Separated x) =
Separated (fmap (\(s, a) -> (a, s)) x)