module Data.API.TH
( applicativeE
, optionalInstanceD
, funSigD
, simpleD
, simpleSigD
, mkNameText
, fieldNameE
, fieldNameVarE
, typeNameE
) where
import Data.API.TH.Compat
import Data.API.Tools.Combinators
import Data.API.Types
import Control.Applicative
import Control.Monad
import qualified Data.Text as T
import Language.Haskell.TH
import Prelude
applicativeE :: ExpQ -> [ExpQ] -> ExpQ
applicativeE ke es0 =
case es0 of
[] -> ke
e:es -> app' (ke `dl` e) es
where
app' e [] = e
app' e (e':es) = app' (e `st` e') es
st e1 e2 = appE (appE (varE '(<*>)) e1) e2
dl e1 e2 = appE (appE (varE '(<$>)) e1) e2
optionalInstanceD :: ToolSettings -> Name -> [TypeQ] -> [DecQ] -> Q [Dec]
optionalInstanceD stgs c tqs dqs = do
ts <- sequence tqs
ds <- sequence dqs
exists <- isInstance c ts
if exists then do when (warnOnOmittedInstance stgs) $ reportWarning $ msg ts
return []
else return [mkInstanceD [] (foldl AppT (ConT c) ts) ds]
where
msg ts = "instance " ++ pprint c ++ " " ++ pprint ts ++ " already exists, so it was not generated"
funSigD :: Name -> TypeQ -> [ClauseQ] -> Q [Dec]
funSigD n t cs = (\ x y -> [x,y]) <$> sigD n t <*> funD n cs
simpleD :: Name -> ExpQ -> Q Dec
simpleD n e = funD n [clause [] (normalB e) []]
simpleSigD :: Name -> TypeQ -> ExpQ -> Q [Dec]
simpleSigD n t e = funSigD n t [clause [] (normalB e) []]
mkNameText :: T.Text -> Name
mkNameText = mkName . T.unpack
fieldNameE :: FieldName -> ExpQ
fieldNameE = stringE . T.unpack . _FieldName
fieldNameVarE :: FieldName -> ExpQ
fieldNameVarE = varE . mkNameText . _FieldName
typeNameE :: TypeName -> ExpQ
typeNameE = stringE . T.unpack . _TypeName