module Data.HList.Labelable
(Labelable(..),
LabeledOptic,
(.==.),
Projected(..), projected',
LabeledCxt1,
LabeledTo(LabeledTo),
LabeledR(LabeledR),
ToSym(toLabel),
Identity,
LabelableTIPCxt,
LabeledOpticType(..),
LabeledOpticF,
LabeledOpticP,
LabeledOpticTo,
) where
import Data.HList.HListPrelude
import Data.HList.FakePrelude
import Data.HList.Record
import Data.HList.Variant
import Data.HList.TIP
import Data.HList.TIC
import Data.HList.Label3
import Control.Monad.Identity
import GHC.TypeLits
import LensDefs
import GHC.Exts (Constraint)
type LabeledOptic (x :: k) (r :: [*] -> *) (s :: [*]) (t :: [*]) (a :: *) (b :: *)
= forall ty to p f.
(ty ~ LabelableTy r,
LabeledOpticF ty f,
LabeledOpticP ty p,
LabeledOpticTo ty x to) => (a `p` f b) `to` (r s `p` f (r t))
data LabeledOpticType = LabelableLens | LabelablePrism | LabelableLabel
type family LabeledOpticF (ty :: LabeledOpticType) :: (* -> *) -> Constraint
type instance LabeledOpticF LabelableLens = Functor
type instance LabeledOpticF LabelablePrism = Applicative
type instance LabeledOpticF LabelableLabel = (~) Identity
type family LabeledOpticP (ty :: LabeledOpticType) :: (* -> * -> *) -> Constraint
type instance LabeledOpticP LabelableLens = (~) (->)
type instance LabeledOpticP LabelablePrism = Choice
type instance LabeledOpticP LabelableLabel = (~) (->)
type family LabeledOpticTo (ty :: LabeledOpticType) (x :: k) :: (* -> * -> *) -> Constraint
type instance LabeledOpticTo LabelableLens x = (~) (->)
type instance LabeledOpticTo LabelablePrism x = (~) (->)
type instance LabeledOpticTo LabelableLabel x = (~) (LabeledTo x)
class SameLength s t => Labelable (x :: k) (r :: [*] -> *) s t a b
| x s -> a, x t -> b,
x s b -> t, x t a -> s
where
type LabelableTy r :: LabeledOpticType
hLens' :: Label x -> LabeledOptic x r s t a b
data LabeledTo (x :: k) (a :: *) (b :: *) = LabeledTo deriving (Show)
data LabeledR (x :: [*]) = LabeledR
instance HLens x Record s t a b
=> Labelable x Record s t a b where
type LabelableTy Record = LabelableLens
hLens' = hLens
instance LabeledCxt1 s t a b => Labelable x LabeledR s t a b where
type LabelableTy LabeledR = LabelableLabel
hLens' _ = LabeledTo
type LabeledCxt1 s t a b = (s ~ '[], t ~ '[], a ~ (), b ~ ())
instance (HPrism x s t a b,
to ~ (->)) => Labelable x Variant s t a b where
type LabelableTy Variant = LabelablePrism
hLens' x s = hPrism x s
instance (TICPrism s t a b, x ~ a, a ~ b, s ~ t,
SameLength s t) =>
Labelable (x :: *) TIC s t a b where
type LabelableTy TIC = LabelablePrism
hLens' _ = ticPrism
instance LabelableTIPCxt x s t a b =>
Labelable x TIP s t a b where
type LabelableTy TIP = LabelableLens
hLens' = hLens
type LabelableTIPCxt x s t a b =
(s ~ t, a ~ b, x ~ a,
HLens x TIP s t a b)
l .==. v = toLabel l .=. v
infixr 4 .==.
class ToSym label (s :: Symbol) | label -> s where
toLabel :: label -> Label s
instance LabeledTo x (a `p` f b) (LabeledR s `p` f (LabeledR t)) ~ v1 v2 v3
=> ToSym (v1 v2 v3) x where
toLabel _ = Label
instance ToSym (label x) x where
toLabel _ = Label
class Projected r s t a b where
projected :: (ty ~ LabelableTy r,
LabeledOpticP ty p,
LabeledOpticF ty f) => r a `p` f (r b) -> r s `p` f (r t)
instance (
H2ProjectByLabels (LabelsOf a) s a_ _s_minus_a,
HRLabelSet a_, HRLabelSet a,
HRearrange (LabelsOf a) a_ a,
HLeftUnion b s bs, HRLabelSet bs,
HRearrange (LabelsOf t) bs t, HRLabelSet t
) => Projected Record s t a b where
projected f s = (\b -> hRearrange' (b .<++. s)) <$> f (hProjectByLabels' s :: Record a)
instance (ExtendsVariant b t,
ProjectVariant s a,
ProjectExtendVariant s t,
HLeftUnion b s bs, HRLabelSet bs,
HRearrange (LabelsOf t) bs t)
=> Projected Variant s t a b where
projected = prism extendsVariant
(\s -> case projectVariant s of
Just a -> Right a
Nothing | Just t <- projectExtendVariant s -> Left t
_ -> error "Data.HList.Labelable.projected impossible"
)
projected' s = simple (projected (simple s))
instance (to ~ LabeledTo x, ToSym (to p q) x)
=> HExtend (to p q) (Proxy ('[] :: [*])) where
type HExtendR (to p q) (Proxy ('[] :: [*])) = Proxy '[GetXFromLabeledTo to]
(.*.) _ _ = Proxy
instance (to ~ LabeledTo x, ToSym (to p q) x)
=> HExtend (to p q) (Proxy (x ': xs)) where
type HExtendR (to p q) (Proxy (x ': xs)) = Proxy (GetXFromLabeledTo to ': x ': xs)
(.*.) _ _ = Proxy
instance (to ~ LabeledTo x, ToSym (to p q) x)
=> HExtend (to p q) (Proxy (Lbl n ns desc ': xs)) where
type HExtendR (to p q) (Proxy (Lbl n ns desc ': xs))
= Proxy (Label (GetXFromLabeledTo to) ': MapLabel (Lbl n ns desc ': xs))
(.*.) _ _ = Proxy
type family GetXFromLabeledTo (to :: * -> * -> *) :: Symbol
type instance GetXFromLabeledTo (LabeledTo x) = x