{-# LANGUAGE CPP #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE TemplateHaskell #-} {-| Template Haskell helpers for Sext. -} module Data.Sext.TH ( sext ) where import Prelude import qualified Prelude as P (length) import Data.Sext.Class import Data.String import Language.Haskell.TH -- | A type with IsString instance to allow string literals in 'sext' -- argument without quoting. newtype LitS = LitS String deriving IsString -- | Type-safe Sext constructor macro for string literals. -- -- Example: -- -- > $(sext "Foobar") -- -- compiles to -- -- > unsafeCreate "Foobar" :: forall a. (IsString a, Sextable a) => Sext 6 a -- -- where 6 is the string length obtained at compile time. sext :: LitS -> Q Exp sext (LitS s) = do at <- newName "a" return $ SigE (AppE (VarE 'unsafeCreate) (LitE $ StringL s)) (ForallT [PlainTV at] #if MIN_VERSION_template_haskell(2,10,0) [ AppT (ConT ''IsString) (VarT at) , AppT (ConT ''Sextable) (VarT at)] $ #else [ ClassP ''IsString [VarT at] , ClassP ''Sextable [VarT at]] $ #endif AppT (AppT (ConT ''Sext) (LitT $ NumTyLit (fromIntegral $ P.length s))) (VarT at))