#if (__GLASGOW_HASKELL__ < 709)
#endif
module Data.HList.Dredge where
import Data.HList.Record
import Data.HList.Variant
import Data.HList.HList
import Data.HList.TIP
import Data.HList.TIC
import Data.HList.FakePrelude
import Data.HList.Labelable
import LensDefs (isSimple)
import Data.HList.TypeEqO ()
#if (__GLASGOW_HASKELL__ == 800)
toLabelx x = toLabelSym x
#else
toLabelx x = toLabel x
#endif
dredge label = getSAfromOutputOptic $ \ pr pa ->
hLens'Path (labelPathEndingWithTD pr (toLabelx label) pa)
getSAfromOutputOptic :: (p a fb -> p rs rft) ~ stab
=> (Proxy (rs :: *) -> Proxy (a :: *) -> stab) -> stab
getSAfromOutputOptic f = f Proxy Proxy
dredge' label = isSimple (dredge label)
dredgeND label = getSAfromOutputOptic $ \ pr _a ->
hLens'Path (labelPathEndingWith pr (toLabelx label))
dredgeND' label = isSimple (dredgeND label)
dredgeTI' label = isSimple lens where
lens = getSAfromOutputOptic $ \ pr pa ->
hLens'Path (labelPathEndingWith pr (pa `proxyTypeOf` label))
proxyTypeOf :: p a -> q a -> Label a
proxyTypeOf _ _ = Label
class HSingleton (msgAmb :: m) (msgEmpty :: m2) (ns :: [k]) (p :: k) | ns -> p
instance HSingleton m1 m2 '[n] n
instance (Fail m2, Any ~ a) => HSingleton m1 m2 '[] a
instance (Fail m1, Any ~ a) => HSingleton m1 m2 (n1 ': n2 ': n3) a
class HGuardNonNull emptymsg (xs :: [k])
instance Fail msg => HGuardNonNull msg '[]
instance HGuardNonNull msg (x ': xs)
class ConsTrue (b :: Bool) (x :: k) (xs :: [k]) (r :: [k]) | b x xs -> r, r b -> xs, x xs r -> b
instance ConsTrue True x xs (x ': xs)
instance ConsTrue False x xs xs
class FilterLastEq (x :: k) (xs :: [[k]]) (ys :: [m]) (ys' :: [m]) | x xs ys -> ys'
instance (HReverse path (y' ': rest), HEq y y' b, ConsTrue b z r1 r,
FilterLastEq y xs zs r1) => FilterLastEq y (path ': xs) (z ': zs) r
instance FilterLastEq y '[] '[] '[]
class FilterVEq (v :: *) (vs :: [*]) (ns :: [k]) (ns' :: [k]) | v vs ns -> ns'
instance FilterVEq v '[] '[] '[]
instance
(HEq v v' b,
ConsTrue b n ns1 ns2,
FilterVEq v vs ns ns1)
=> FilterVEq v (v' ': vs) (n ': ns) ns2
class FilterVEq1 (v :: *) (vs :: [*]) (ns :: [k]) (ns' :: [k]) | v vs ns -> ns'
instance (v ~ v') => FilterVEq1 v '[ v' ] ns ns
instance FilterVEq1 v '[] '[] '[]
instance FilterVEq v (a ': b ': c) ns ns' => FilterVEq1 v (a ': b ': c) ns ns'
class LabelPathEndingWith (r :: *) (l :: k) (path :: [*]) | r l -> path where
labelPathEndingWith :: proxy r -> Label l -> Label path
labelPathEndingWith _ _ = Label
instance
(FieldTree r ns,
FilterLastEq (Label l) ns ns ns',
HSingleton (NonUnique' r l) (NamesDontMatch r ns l) ns' path)
=> LabelPathEndingWith r l path
labelPathEndingWithTD :: forall r l v path
vs vs1 ns ns1 ns2.
(SameLength ns vs,
SameLength ns1 vs1,
FieldTree r ns,
FieldTreeVal r vs,
FilterLastEq (Label l) ns ns ns1,
FilterLastEq (Label l) ns vs vs1,
FilterVEq1 v vs1 ns1 ns2,
HGuardNonNull (NamesDontMatch r ns l) ns1,
HSingleton (NonUnique r v l) (TypesDontMatch r ns1 vs1 v) ns2 path)
=> Proxy r -> Label l -> Proxy v -> Label path
labelPathEndingWithTD _ _ _ = Label
type NamesDontMatch r ns l = ErrShowType r
:$$: ErrText "has paths" :<>: ErrShowType ns
:$$: ErrText "but none which end in the desired label" :<>: ErrShowType l
type NonUnique' r l = ErrText "Path ending in label " :<>: ErrShowType l
:$$: ErrText "is not unique in " :<>: ErrShowType r
type NonUnique r v l = NonUnique' r l
:$$: ErrText "also considering the v type " :<>: ErrShowType v
type TypesDontMatch r ns1 vs1 v = ErrShowType r
:$$: ErrText "has potential paths with the right labels" :<>: ErrShowType ns1
:$$: ErrText "which point at types" :<>: ErrShowType vs1 :<>: ErrText "respectively"
:$$: ErrText "but none of these match the desired type" :<>: ErrShowType v
hLookupByLabelDredge l r = labelPathEndingWith (toProxy r) l `hLookupByLabelPath` r
where toProxy :: r x -> Proxy x
toProxy _ = Proxy
hLookupByLabelPath :: HasFieldPath False ls r v => Label ls -> r -> v
hLookupByLabelPath labels r = hLookupByLabelPath1 hFalse labels r
class LabelablePath (xs :: [*]) apb spt | spt xs -> apb where
hLens'Path :: Label xs -> apb -> spt
instance (Labelable x r s t a b,
j ~ (a `p` f b),
k ~ (r s `p` f (r t)),
ty ~ LabelableTy r,
LabeledOpticP ty p,
LabeledOpticF ty f,
LabeledOpticTo ty x (->),
LabelablePath xs i j) => LabelablePath (Label x ': xs) i k where
hLens'Path _ = (hLens' (Label :: Label x) :: j -> k) . hLens'Path (Label :: Label xs)
instance (x ~ x') => LabelablePath '[] x x' where
hLens'Path _ = id
class HasFieldPath (needJust :: Bool) (ls :: [*]) r v | needJust ls r -> v where
hLookupByLabelPath1 :: Proxy needJust -> Label ls -> r -> v
instance HasFieldPath False '[] v v where
hLookupByLabelPath1 _ _ = id
instance HasFieldPath True '[] v (Maybe v) where
hLookupByLabelPath1 _ _ = Just
instance (HasField l (Record r) u, HasFieldPath needJust ls u v)
=> HasFieldPath needJust (Label l ': ls) (Record r) v where
hLookupByLabelPath1 needJust _ = hLookupByLabelPath1 needJust (Label :: Label ls)
. hLookupByLabel (Label :: Label l)
instance (HasField l (Variant r) (Maybe u), HasFieldPath True ls u (Maybe v))
=> HasFieldPath needJust (Label l ': ls) (Variant r) (Maybe v) where
hLookupByLabelPath1 _ _ v = hLookupByLabelPath1 hTrue (Label :: Label ls) =<< hLookupByLabel (Label :: Label l) v
class FieldTreeVal (r :: *) (v :: [*]) | r -> v
class MapFieldTreeVal (r :: *) (ns :: Maybe [*]) (vs :: [*]) | r ns -> vs
instance (TryCollectionList r ns, MapFieldTreeVal r ns v) => FieldTreeVal r v
instance MapFieldTreeVal r Nothing '[]
instance ( MapFieldTreeVal r (Just xs) out2,
FieldTreeVal v out1,
(v ': HAppendListR out1 out2) ~ out)
=> MapFieldTreeVal r (Just (Tagged n v ': xs)) out
instance MapFieldTreeVal r (Just '[]) '[]
class FieldTree (r :: *) (v :: [[*]]) | r -> v
instance (TryCollectionList r ns, MapFieldTree ns vs) => FieldTree r vs
#if (__GLASGOW_HASKELL__ >= 800)
type family TryCollectionListTF (r :: *) :: Maybe [*] where
TryCollectionListTF (Record r) = Just r
TryCollectionListTF (Variant r) = Just r
TryCollectionListTF (TIC r) = Just r
TryCollectionListTF (TIP r) = Just r
TryCollectionListTF nothing = Nothing
type TryCollectionList r v = (v ~ TryCollectionListTF r)
#else
class TryCollectionList (r :: *) (v :: Maybe [*]) | r -> v
instance (nothing ~ Nothing) => TryCollectionList x nothing
instance TryCollectionList (Record r) (Just r)
instance TryCollectionList (Variant r) (Just r)
instance TryCollectionList (TIC r) (Just r)
instance TryCollectionList (TIP r) (Just r)
#endif
class MapFieldTree (ns :: Maybe [*]) (vs :: [[*]]) | ns -> vs
instance MapFieldTree Nothing '[]
instance (
MapFieldTree (Just xs) vs3,
FieldTree v vs1,
MapCons (Label n) ('[] ': vs1) vs2,
HAppendListR vs2 vs3 ~ vs)
=> MapFieldTree (Just (Tagged n v ': xs)) vs
instance MapFieldTree (Just '[]) '[]
class MapCons (x :: k) (xs :: [[k]]) (xxs :: [[k]]) | x xs -> xxs
instance MapCons x '[] '[]
instance MapCons x b r => MapCons x (a ': b) ( (x ': a) ': r)