module Data.HList.TIC where
import Data.HList.TIP
import Data.HList.FakePrelude
import Data.HList.HListPrelude
import Data.HList.Record
import Data.HList.Variant
import Data.HList.HList
import Data.HList.HArray
import Data.Array (Ix)
import Data.Semigroup (Semigroup)
import Text.ParserCombinators.ReadP
import LensDefs
newtype TIC (l :: [*]) = TIC (Variant l)
deriving instance Eq (Variant l) => Eq (TIC l)
deriving instance Ord (Variant l) => Ord (TIC l)
deriving instance Ix (Variant l) => Ix (TIC l)
deriving instance Bounded (Variant l) => Bounded (TIC l)
deriving instance Enum (Variant l) => Enum (TIC l)
deriving instance Monoid (Variant l) => Monoid (TIC l)
deriving instance Semigroup (Variant l) => Semigroup (TIC l)
instance HMapAux Variant f xs ys => HMapAux TIC f xs ys where
hMapAux f (TIC a) = TIC (hMapAux f a)
ticVariant x = isoNewtype (\(TIC a) -> a) TIC x
ticVariant' x = isSimple ticVariant x
class TypeIndexed r tr | r -> tr, tr -> r where
typeIndexed :: forall p f s t a b.
(TypeIndexedCxt s t a b, Profunctor p, Functor f) =>
p (tr (TagR a)) (f (tr (TagR b))) -> p (r s) (f (r t))
type TypeIndexedCxt s t a b =
(HMapCxt HList TaggedFn b t,
RecordValues s, RecordValues t,
a ~ RecordValuesR s,
b ~ RecordValuesR t,
SameLabels s t,
SameLength s t,
SameLength b a,
Coercible (TagR b) t,
Coercible (TagR a) s,
HAllTaggedLV s,
HRLabelSet t,
TagUntag a,
TagUntag b)
instance TypeIndexed Record TIP where
typeIndexed = sameLength . unlabeled . fromTipHList
where fromTipHList = iso (TIP . hTagSelf) (\(TIP a) -> hUntagSelf a)
instance TypeIndexed Variant TIC where
typeIndexed = isoNewtype unsafeCastVariant unsafeCastVariant
. isoNewtype TIC (\(TIC a) -> a)
typeIndexed' x = isSimple typeIndexed x
mkTIC' :: forall i l proxy.
( HTypeIndexed l
, MkVariant i i l
)
=> i
-> proxy l
-> TIC l
mkTIC' i p = TIC (mkVariant (Label :: Label i) i p)
mkTIC1 :: forall i. MkVariant i i '[Tagged i i] => i -> TIC '[Tagged i i]
mkTIC1 i = TIC (mkVariant1 (Label :: Label i) i)
mkTIC i = mkTIC' i Proxy
instance HasField o (Variant l) (Maybe o) =>
HasField o (TIC l) (Maybe o) where
hLookupByLabel l (TIC i) = hLookupByLabel l i
instance (HasField o (TIC l) mo, mo ~ Maybe o) => HOccurs mo (TIC l) where
hOccurs = hLookupByLabel (Label :: Label o)
class TICPrism s t a b | s a b -> t, t a b -> s where
ticPrism :: (SameLength s t, Choice p, Applicative f)
=> (a `p` f b) -> (TIC s `p` f (TIC t))
instance (
MkVariant b b t,
HasField a (Variant s) (Maybe a),
SameLength s t,
HFindLabel b t n,
HFindLabel a s n,
HUpdateAtHNatR n (Tagged b b) s ~ t,
HUpdateAtHNatR n (Tagged a a) t ~ s
) => TICPrism s t a b where
ticPrism = ticVariant . prism (\b -> mkVariant (Label :: Label b) b Proxy)
(\s -> case hLookupByLabel (Label :: Label a) s of
Just a -> Right a
Nothing -> Left (unsafeCastVariant s :: Variant t))
ticPrism' :: forall s t a b. (HPrism a s t a b, a~b, s~t)
=> (forall f p. (Applicative f, Choice p) => (a `p` f b) -> (TIC s `p` f (TIC t)))
ticPrism' = ticVariant . hPrism (Label :: Label a)
instance ShowVariant l => Show (TIC l)
where
showsPrec _ (TIC v) = ("TIC{"++) . showVariant v . ('}':)
instance (ReadVariant l, HAllTaggedEq l, HRLabelSet l) => Read (TIC l)
where
readsPrec _ = readP_to_S $ do
_ <- string "TIC{"
r <- readVariant
_ <- string "}"
return (TIC r)
instance (me ~ Maybe e, HOccursNot (Tagged e e) l)
=> HExtend me (TIC l) where
type HExtendR me (TIC l) = TIC (Tagged (UnMaybe me) (UnMaybe me) ': l)
Just e .*. _ = TIC (unsafeMkVariant 0 e)
Nothing .*. TIC x = TIC (extendVariant x)