{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}
module Generics.SOP.Universe where
import Data.Kind (Type)
import Data.Coerce (Coercible, coerce)
import Data.Proxy
import qualified GHC.Generics as GHC
import Generics.SOP.BasicFunctors
import Generics.SOP.Constraint
import Generics.SOP.NP
import Generics.SOP.NS
import Generics.SOP.GGP
import Generics.SOP.Metadata
import qualified Generics.SOP.Type.Metadata as T
type Rep a = SOP I (Code a)
class (All SListI (Code a)) => Generic (a :: Type) where
type Code a :: [[Type]]
type Code a = GCode a
from :: a -> Rep a
default from :: (GFrom a, GHC.Generic a, Rep a ~ SOP I (GCode a))
=> a -> Rep a
from = a -> SOP I (GCode a)
a -> Rep a
forall a. (GFrom a, Generic a) => a -> SOP I (GCode a)
gfrom
to :: Rep a -> a
default to :: (GTo a, GHC.Generic a, Rep a ~ SOP I (GCode a))
=> Rep a -> a
to = SOP I (GCode a) -> a
Rep a -> a
forall a. (GTo a, Generic a) => SOP I (GCode a) -> a
gto
class Generic a => HasDatatypeInfo a where
type DatatypeInfoOf a :: T.DatatypeInfo
type DatatypeInfoOf a = GDatatypeInfoOf a
datatypeInfo :: proxy a -> DatatypeInfo (Code a)
default datatypeInfo :: (GDatatypeInfo a, GCode a ~ Code a) => proxy a -> DatatypeInfo (Code a)
datatypeInfo = proxy a -> DatatypeInfo (GCode a)
proxy a -> DatatypeInfo (Code a)
forall (proxy :: * -> *) a.
GDatatypeInfo a =>
proxy a -> DatatypeInfo (GCode a)
gdatatypeInfo
type IsProductType (a :: Type) (xs :: [Type]) =
(Generic a, Code a ~ '[ xs ])
type ProductCode (a :: Type) =
Head (Code a)
productTypeFrom :: IsProductType a xs => a -> NP I xs
productTypeFrom :: forall a (xs :: [*]). IsProductType a xs => a -> NP I xs
productTypeFrom = NS (NP I) '[xs] -> NP I xs
forall {k} (f :: k -> *) (x :: k). NS f '[x] -> f x
unZ (NS (NP I) '[xs] -> NP I xs)
-> (a -> NS (NP I) '[xs]) -> a -> NP I xs
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SOP I '[xs] -> NS (NP I) '[xs]
forall {k} (f :: k -> *) (xss :: [[k]]). SOP f xss -> NS (NP f) xss
unSOP (SOP I '[xs] -> NS (NP I) '[xs])
-> (a -> SOP I '[xs]) -> a -> NS (NP I) '[xs]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> SOP I '[xs]
a -> Rep a
forall a. Generic a => a -> Rep a
from
{-# INLINE productTypeFrom #-}
productTypeTo :: IsProductType a xs => NP I xs -> a
productTypeTo :: forall a (xs :: [*]). IsProductType a xs => NP I xs -> a
productTypeTo = SOP I '[xs] -> a
Rep a -> a
forall a. Generic a => Rep a -> a
to (SOP I '[xs] -> a) -> (NP I xs -> SOP I '[xs]) -> NP I xs -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NS (NP I) '[xs] -> SOP I '[xs]
forall k (f :: k -> *) (xss :: [[k]]). NS (NP f) xss -> SOP f xss
SOP (NS (NP I) '[xs] -> SOP I '[xs])
-> (NP I xs -> NS (NP I) '[xs]) -> NP I xs -> SOP I '[xs]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NP I xs -> NS (NP I) '[xs]
forall {k} (a :: k -> *) (x :: k) (xs :: [k]). a x -> NS a (x : xs)
Z
{-# INLINE productTypeTo #-}
type IsEnumType (a :: Type) =
(Generic a, All ((~) '[]) (Code a))
enumTypeFrom :: IsEnumType a => a -> NS (K ()) (Code a)
enumTypeFrom :: forall a. IsEnumType a => a -> NS (K ()) (Code a)
enumTypeFrom = (forall (a :: [*]). NP I a -> K () a)
-> NS (NP I) (Code a) -> NS (K ()) (Code a)
forall {k} (xs :: [k]) (f :: k -> *) (g :: k -> *).
SListI xs =>
(forall (a :: k). f a -> g a) -> NS f xs -> NS g xs
map_NS (K () a -> NP I a -> K () a
forall a b. a -> b -> a
const (() -> K () a
forall k a (b :: k). a -> K a b
K ())) (NS (NP I) (Code a) -> NS (K ()) (Code a))
-> (a -> NS (NP I) (Code a)) -> a -> NS (K ()) (Code a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SOP I (Code a) -> NS (NP I) (Code a)
forall {k} (f :: k -> *) (xss :: [[k]]). SOP f xss -> NS (NP f) xss
unSOP (SOP I (Code a) -> NS (NP I) (Code a))
-> (a -> SOP I (Code a)) -> a -> NS (NP I) (Code a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> SOP I (Code a)
forall a. Generic a => a -> Rep a
from
{-# INLINE enumTypeFrom #-}
enumTypeTo :: IsEnumType a => NS (K ()) (Code a) -> a
enumTypeTo :: forall a. IsEnumType a => NS (K ()) (Code a) -> a
enumTypeTo = Rep a -> a
forall a. Generic a => Rep a -> a
to (Rep a -> a)
-> (NS (K ()) (Code a) -> Rep a) -> NS (K ()) (Code a) -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NS (NP I) (Code a) -> Rep a
forall k (f :: k -> *) (xss :: [[k]]). NS (NP f) xss -> SOP f xss
SOP (NS (NP I) (Code a) -> Rep a)
-> (NS (K ()) (Code a) -> NS (NP I) (Code a))
-> NS (K ()) (Code a)
-> Rep a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy ((~) '[])
-> (forall (a :: [*]). ('[] ~ a) => K () a -> NP I a)
-> NS (K ()) (Code a)
-> NS (NP I) (Code a)
forall {k} (c :: k -> Constraint) (xs :: [k])
(proxy :: (k -> Constraint) -> *) (f :: k -> *) (g :: k -> *).
All c xs =>
proxy c
-> (forall (a :: k). c a => f a -> g a) -> NS f xs -> NS g xs
cmap_NS (Proxy ((~) '[])
forall {k} (t :: k). Proxy t
Proxy :: Proxy ((~) '[])) (NP I a -> K () a -> NP I a
forall a b. a -> b -> a
const NP I a
NP I '[]
forall {k} (a :: k -> *). NP a '[]
Nil)
{-# INLINE enumTypeTo #-}
type IsWrappedType (a :: Type) (x :: Type) =
(Generic a, Code a ~ '[ '[ x ] ])
type WrappedCode (a :: Type) =
Head (Head (Code a))
wrappedTypeFrom :: IsWrappedType a x => a -> x
wrappedTypeFrom :: forall a x. IsWrappedType a x => a -> x
wrappedTypeFrom = I x -> x
forall a. I a -> a
unI (I x -> x) -> (a -> I x) -> a -> x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NP I '[x] -> I x
forall {k} (f :: k -> *) (x :: k) (xs :: [k]). NP f (x : xs) -> f x
hd (NP I '[x] -> I x) -> (a -> NP I '[x]) -> a -> I x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NS (NP I) '[ '[x]] -> NP I '[x]
forall {k} (f :: k -> *) (x :: k). NS f '[x] -> f x
unZ (NS (NP I) '[ '[x]] -> NP I '[x])
-> (a -> NS (NP I) '[ '[x]]) -> a -> NP I '[x]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SOP I '[ '[x]] -> NS (NP I) '[ '[x]]
forall {k} (f :: k -> *) (xss :: [[k]]). SOP f xss -> NS (NP f) xss
unSOP (SOP I '[ '[x]] -> NS (NP I) '[ '[x]])
-> (a -> SOP I '[ '[x]]) -> a -> NS (NP I) '[ '[x]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> SOP I '[ '[x]]
a -> Rep a
forall a. Generic a => a -> Rep a
from
{-# INLINE wrappedTypeFrom #-}
wrappedTypeTo :: IsWrappedType a x => x -> a
wrappedTypeTo :: forall a x. IsWrappedType a x => x -> a
wrappedTypeTo = SOP I '[ '[x]] -> a
Rep a -> a
forall a. Generic a => Rep a -> a
to (SOP I '[ '[x]] -> a) -> (x -> SOP I '[ '[x]]) -> x -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NS (NP I) '[ '[x]] -> SOP I '[ '[x]]
forall k (f :: k -> *) (xss :: [[k]]). NS (NP f) xss -> SOP f xss
SOP (NS (NP I) '[ '[x]] -> SOP I '[ '[x]])
-> (x -> NS (NP I) '[ '[x]]) -> x -> SOP I '[ '[x]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NP I '[x] -> NS (NP I) '[ '[x]]
forall {k} (a :: k -> *) (x :: k) (xs :: [k]). a x -> NS a (x : xs)
Z (NP I '[x] -> NS (NP I) '[ '[x]])
-> (x -> NP I '[x]) -> x -> NS (NP I) '[ '[x]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (I x -> NP I '[] -> NP I '[x]
forall {k} (a :: k -> *) (x :: k) (xs :: [k]).
a x -> NP a xs -> NP a (x : xs)
:* NP I '[]
forall {k} (a :: k -> *). NP a '[]
Nil) (I x -> NP I '[x]) -> (x -> I x) -> x -> NP I '[x]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> I x
forall a. a -> I a
I
{-# INLINE wrappedTypeTo #-}
type IsNewtype (a :: Type) (x :: Type) =
(IsWrappedType a x, Coercible a x)
newtypeFrom :: IsNewtype a x => a -> x
newtypeFrom :: forall a x. IsNewtype a x => a -> x
newtypeFrom = a -> x
forall a b. Coercible a b => a -> b
coerce
{-# INLINE newtypeFrom #-}
newtypeTo :: IsNewtype a x => x -> a
newtypeTo :: forall a x. IsNewtype a x => x -> a
newtypeTo = x -> a
forall a b. Coercible a b => a -> b
coerce
{-# INLINE newtypeTo #-}