{-# LANGUAGE TemplateHaskell, PolyKinds #-}
module Arity where
import Data.Proxy
import Language.Haskell.TH
class TypeArity (cla :: k) where
arity :: Proxy cla -> Integer
getTypeArity :: Name -> Q Int
getTypeArity name = do
info <- reify name
case info of
TyConI dec -> case dec of
DataD _ _ tvbs _ _ _ -> return $ length tvbs
NewtypeD _ _ tvbs _ _ _ -> return $ length tvbs
_ -> error "The type must be data, newtype definition!"
PrimTyConI _ n _ -> return n
x -> error $ show x ++ " is bad type name, quoted name is not a type!"
makeTypeArity :: Name -> Q [Dec]
makeTypeArity name = do
at <- getTypeArity name
[d| instance TypeArity $(conT name) where
arity _ = at |]