packages feed

graph-trace-0.1.0.1: src/Graph/Trace/Internal/TH.hs

{-# LANGUAGE CPP #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DataKinds #-}
module Graph.Trace.Internal.TH
  ( makeInstancesForRep
  , allRuntimeReps
  ) where

import           Control.Monad
import           Data.Traversable
import           GHC.Exts
#if MIN_VERSION_ghc(9,0,0)
import           GHC.Types (Multiplicity(..))
#endif
import           Language.Haskell.TH

-- | A splice for generating instances for a given RuntimeRep
makeInstancesForRep :: Name -> Name -> Q Type -> Q [InstanceDec]
makeInstancesForRep cls meth rep = do
  let instTypes =
#if MIN_VERSION_ghc(9,0,0)
        [ conT cls `appT` rep `appT` [t| One |]
        , conT cls `appT` rep `appT` [t| Many |]
        ]
#else
        [ conT cls `appT` rep ]
#endif
  for instTypes $ \instType -> do
    x <- newName "x"
    instanceD (pure []) instType
      [ funD meth [clause [varP x] (normalB $ varE x) []] ]

-- | RuntimeReps to generate instances for
runtimeReps :: [Q Type]
runtimeReps =
  [ [t| LiftedRep   |]
  , [t| UnliftedRep |]
  , [t| IntRep      |]
  , [t| Int8Rep     |]
  , [t| Int16Rep    |]
  , [t| Int32Rep    |]
  , [t| Int64Rep    |]
  , [t| WordRep     |]
  , [t| Word8Rep    |]
  , [t| Word16Rep   |]
  , [t| Word32Rep   |]
  , [t| Word64Rep   |]
  , [t| AddrRep     |]
  , [t| FloatRep    |]
  , [t| DoubleRep   |]
  ]

tupleReps :: [[Q Type]]
tupleReps = do
  len <- [0..2]
  replicateM len runtimeReps

unboxedTupleReps :: [Q Type]
unboxedTupleReps = map go tupleReps where
  go tupleRep = do
    tys <- sequence tupleRep
    let list = foldr (AppT . AppT PromotedConsT) PromotedNilT tys
    conT 'TupleRep `appT` pure list

unboxedSumReps :: [Q Type]
unboxedSumReps = map go tupleReps where
  go tupleRep = do
    tys <- sequence tupleRep
    let list = foldr (AppT . AppT PromotedConsT) PromotedNilT tys
    conT 'SumRep `appT` pure list

-- Does not include SIMD vectors b/c they are platform dependent
allRuntimeReps :: [Q Type]
allRuntimeReps = runtimeReps <> unboxedTupleReps <> unboxedSumReps