{-# LANGUAGE PolyKinds #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} module Hpack.GenericsUtil ( HasTypeName , typeName , Selectors , selectors ) where import Data.Proxy import GHC.Generics class HasTypeName a where typeName :: Proxy a -> String instance (Datatype d, Generic a, Rep a ~ M1 D d m) => HasTypeName a where typeName _ = datatypeName (undefined :: M1 D d x y) selectors :: (Selectors (Rep a)) => Proxy a -> [String] selectors = f where f :: forall a. (Selectors (Rep a)) => Proxy a -> [String] f _ = selNames (Proxy :: Proxy (Rep a)) class Selectors a where selNames :: Proxy a -> [String] instance Selectors f => Selectors (M1 D x f) where selNames _ = selNames (Proxy :: Proxy f) instance Selectors f => Selectors (M1 C x f) where selNames _ = selNames (Proxy :: Proxy f) instance Selector s => Selectors (M1 S s (K1 R t)) where selNames _ = [selName (undefined :: M1 S s (K1 R t) ())] instance (Selectors a, Selectors b) => Selectors (a :*: b) where selNames _ = selNames (Proxy :: Proxy a) ++ selNames (Proxy :: Proxy b) instance Selectors U1 where selNames _ = []