{-# LANGUAGE UndecidableInstances #-}
module Z.Data.Generics.Utils
( ProductSize(..)
, productSize
, SumSize(..)
, sumSize
) where
import GHC.Generics
import GHC.TypeNats
import GHC.Exts (Proxy#, proxy#)
import Data.Kind
class KnownNat (PSize f) => ProductSize (f :: Type -> Type) where
type PSize f :: Nat
instance ProductSize (S1 s a) where
type PSize (S1 s a) = 1
instance (KnownNat (PSize a + PSize b), ProductSize a, ProductSize b) => ProductSize (a :*: b) where
type PSize (a :*: b) = PSize a + PSize b
productSize :: forall f. KnownNat (PSize f) => Proxy# f -> Int
{-# INLINE productSize #-}
productSize :: forall (f :: * -> *). KnownNat (PSize f) => Proxy# f -> Int
productSize Proxy# f
_ = forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (n :: Natural). KnownNat n => Proxy# n -> Natural
natVal' (forall {k} (a :: k). Proxy# a
proxy# :: Proxy# (PSize f)))
class KnownNat (SSize f) => SumSize (f :: Type -> Type) where
type SSize f :: Nat
instance SumSize (C1 c a) where
type SSize (C1 c a) = 1
instance (KnownNat (SSize a + SSize b), SumSize a, SumSize b) => SumSize (a :+: b) where
type SSize (a :+: b) = SSize a + SSize b
sumSize :: forall f. KnownNat (SSize f) => Proxy# f -> Int
{-# INLINE sumSize #-}
sumSize :: forall (f :: * -> *). KnownNat (SSize f) => Proxy# f -> Int
sumSize Proxy# f
_ = forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (n :: Natural). KnownNat n => Proxy# n -> Natural
natVal' (forall {k} (a :: k). Proxy# a
proxy# :: Proxy# (SSize f)))