module Data.Iso.Common (
unit,
tup,
tup3,
nothing, just, maybe,
nil, cons,
left, right, either,
false, true, bool
) where
import Prelude hiding (id, (.), maybe, either)
import Control.Category
import Data.Iso.Core
import Data.Iso.TH
import Data.Semigroup
unit :: Iso t (() :- t)
unit = Iso f g
where
f t = Just (() :- t)
g (_ :- t) = Just t
tup :: Iso (a :- b :- t) ((a, b) :- t)
tup = Iso f g
where
f (a :- b :- t) = Just ((a, b) :- t)
g ((a, b) :- t) = Just (a :- b :- t)
tup3 :: Iso (a :- b :- c :- t) ((a, b, c) :- t)
tup3 = Iso f g
where
f (a :- b :- c :- t) = Just ((a, b, c) :- t)
g ((a, b, c) :- t) = Just (a :- b :- c :- t)
nothing :: Iso t (Maybe a :- t)
just :: Iso (a :- t) (Maybe a :- t)
(nothing, just) = $(deriveIsos ''Maybe)
maybe :: Iso t (a :- t) -> Iso t (Maybe a :- t)
maybe el = just . el <> nothing
nil :: Iso t ([a] :- t)
nil = Iso f g
where
f t = Just ([] :- t)
g ([] :- t) = Just t
g _ = Nothing
cons :: Iso (a :- [a] :- t) ([a] :- t)
cons = Iso f g
where
f (x :- xs :- t) = Just ((x : xs) :- t)
g ((x : xs) :- t) = Just (x :- xs :- t)
g _ = Nothing
left :: Iso (a :- t) (Either a b :- t)
right :: Iso (b :- t) (Either a b :- t)
(left, right) = $(deriveIsos ''Either)
either :: Iso t1 (a :- t2) -> Iso t1 (b :- t2) -> Iso t1 (Either a b :- t2)
either f g = left . f <> right . g
false :: Iso t (Bool :- t)
true :: Iso t (Bool :- t)
(false, true) = $(deriveIsos ''Bool)
bool :: Iso t (Bool :- t)
bool = false <> true