{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell #-}
module Data.Array.Accelerate.Classes.FromIntegral (
FromIntegral(..),
) where
import Data.Array.Accelerate.Smart
import Data.Array.Accelerate.Type
import Data.Array.Accelerate.Classes.Integral
import Language.Haskell.TH hiding ( Exp )
import Prelude hiding ( Integral )
class FromIntegral a b where
fromIntegral :: Integral a => Exp a -> Exp b
$(runQ $ do
let
digItOut :: Name -> Q [Name]
digItOut name = do
#if __GLASGOW_HASKELL__ < 800
TyConI (DataD _ _ _ cons _) <- reify name
#else
TyConI (DataD _ _ _ _ cons _) <- reify name
#endif
let
dig (NormalC _ [(_, AppT (ConT n) (VarT _))]) = digItOut n
#if __GLASGOW_HASKELL__ < 800
dig (ForallC _ _ (NormalC _ [(_, AppT (ConT _) (ConT n))])) = return [n]
#else
dig (GadtC _ _ (AppT (ConT _) (ConT n))) = return [n]
#endif
dig _ = error "Unexpected case generating FromIntegral instances"
concat `fmap` mapM dig cons
thFromIntegral :: Name -> Name -> Q Dec
thFromIntegral a b =
let
ty = AppT (AppT (ConT (mkName "FromIntegral")) (ConT a)) (ConT b)
dec = ValD (VarP (mkName "fromIntegral")) (NormalB (VarE (mkName "mkFromIntegral"))) []
in
instanceD (return []) (return ty) [return dec]
as <- digItOut ''IntegralType
bs <- digItOut ''NumType
sequence [ thFromIntegral a b | a <- as, b <- bs ]
)