{-# 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 = 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 = 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 = 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 = forall {k} (f :: k -> *) (x :: k). NS f '[x] -> f x
unZ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (f :: k -> *) (xss :: [[k]]). SOP f xss -> NS (NP f) xss
unSOP forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall a. Generic a => Rep a -> a
to forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k (f :: k -> *) (xss :: [[k]]). NS (NP f) xss -> SOP f xss
SOP forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 {k} (xs :: [k]) (f :: k -> *) (g :: k -> *).
SListI xs =>
(forall (a :: k). f a -> g a) -> NS f xs -> NS g xs
map_NS (forall a b. a -> b -> a
const (forall k a (b :: k). a -> K a b
K ())) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (f :: k -> *) (xss :: [[k]]). SOP f xss -> NS (NP f) xss
unSOP forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall a. Generic a => Rep a -> a
to forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k (f :: k -> *) (xss :: [[k]]). NS (NP f) xss -> SOP f xss
SOP forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 (forall {k} (t :: k). Proxy t
Proxy :: Proxy ((~) '[])) (forall a b. a -> b -> a
const 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 = forall a. I a -> a
unI forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (f :: k -> *) (x :: k) (xs :: [k]). NP f (x : xs) -> f x
hd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (f :: k -> *) (x :: k). NS f '[x] -> f x
unZ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (f :: k -> *) (xss :: [[k]]). SOP f xss -> NS (NP f) xss
unSOP forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall a. Generic a => Rep a -> a
to forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k (f :: k -> *) (xss :: [[k]]). NS (NP f) xss -> SOP f xss
SOP forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (a :: k -> *) (x :: k) (xs :: [k]). a x -> NS a (x : xs)
Z forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall {k} (a :: k -> *) (x :: k) (xs :: [k]).
a x -> NP a xs -> NP a (x : xs)
:* forall {k} (a :: k -> *). NP a '[]
Nil) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = coerce :: 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 = coerce :: forall a b. Coercible a b => a -> b
coerce
{-# INLINE newtypeTo #-}