{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
module Z.Data.Generics.Utils
( ProductSize(..)
, productSize
) where
import GHC.Generics
import GHC.TypeNats
import GHC.Exts (Proxy#, proxy#)
class KnownNat (PSize f) => ProductSize (f :: * -> *) 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
productSize :: Proxy# f -> Int
productSize Proxy# f
_ = Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy# (PSize f) -> Natural
forall (n :: Nat). KnownNat n => Proxy# n -> Natural
natVal' (Proxy# (PSize f)
forall k (a :: k). Proxy# a
proxy# :: Proxy# (PSize f)))