{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TupleSections #-}
module QQ where
import CustomInterpolation
import Data.Char
import Language.Haskell.TH (appE, listE, Exp, Q)
import Language.Haskell.TH.Quote (QuasiQuoter (..))
itest :: QuasiQuoter
itest =
interpolateQQ
simpleConfig
{ handlers =
[ simpleInterpolator {prefix = "$"},
(applyInterpolator [|show . (+ 1)|]) {prefix = "++"}
]
}
iManyBrackets :: QuasiQuoter
iManyBrackets =
interpolateQQ
simpleConfig
{ handlers =
[ (applyInterpolator [|show|]) {prefix = "$", brackets = roundBrackets},
simpleInterpolator {prefix = "$", brackets = angleBrackets},
(applyInterpolator [|show . take 4|]) {brackets = squareBrackets},
(applyInterpolator [|map toUpper|]) {brackets = curlyBrackets}
]
}
-- readme stuff
i =
interpolateQQ
simpleConfig
{ handlers =
[ simpleInterpolator {prefix = ""},
(applyInterpolator [|show . take 10|]) {prefix = "@"}
]
}
-- Need an existential type to wrap the differently typed interpolated expression
data SQLData = forall a. Show a => SQLData a
instance Show SQLData where show (SQLData x) = show x
-- Dummy function that would normally run the query
runSQL sql' ds = (sql', ds)
-- The quasiquoter itself
consumeInterpolated :: ([Q Exp], Q Exp) -> Q Exp
consumeInterpolated (exprs, strExpr) = appE (appE [|runSQL|] strExpr) (listE (map (appE [|SQLData|]) exprs))
sql =
interpolateQQ
defaultConfig
{ finalize = consumeInterpolated,
handlers = [simpleInterpolator {handler = (\q -> (q, [|"?"|]))}]
}