{-# LANGUAGE CPP #-}
#ifndef MIN_VERSION_template_haskell
#define MIN_VERSION_template_haskell(x,y,z) 1
#endif
#if __GLASGOW_HASKELL__ >= 802
{-# LANGUAGE Safe #-}
#elif __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif
module Data.Proxy.TH
( pr
#if MIN_VERSION_template_haskell(2,8,0)
, pr1
#endif
) where
import Data.Char
#if __GLASGOW_HASKELL__ < 710
import Data.Functor
#endif
#if __GLASGOW_HASKELL__ < 707
import Data.Version (showVersion)
import Paths_tagged
#endif
import Language.Haskell.TH
import Language.Haskell.TH.Quote
import Language.Haskell.TH.Syntax
proxy_d, proxy_tc :: Name
#if __GLASGOW_HASKELL__ >= 707
proxy_d :: Name
proxy_d = String -> String -> String -> Name
mkNameG_d String
"base" String
"Data.Proxy" String
"Proxy"
proxy_tc :: Name
proxy_tc = String -> String -> String -> Name
mkNameG_tc String
"base" String
"Data.Proxy" String
"Proxy"
#else
proxy_d = mkNameG_d taggedPackageKey "Data.Proxy" "Proxy"
proxy_tc = mkNameG_tc taggedPackageKey "Data.Proxy" "Proxy"
taggedPackageKey :: String
taggedPackageKey = "tagged-" ++ showVersion version
#endif
proxyTypeQ :: TypeQ -> TypeQ
proxyTypeQ :: TypeQ -> TypeQ
proxyTypeQ TypeQ
t = forall (m :: * -> *). Quote m => m Type -> m Type -> m Type
appT (forall (m :: * -> *). Quote m => Name -> m Type
conT Name
proxy_tc) TypeQ
t
proxyExpQ :: TypeQ -> ExpQ
proxyExpQ :: TypeQ -> ExpQ
proxyExpQ TypeQ
t = forall (m :: * -> *). Quote m => m Exp -> m Type -> m Exp
sigE (forall (m :: * -> *). Quote m => Name -> m Exp
conE Name
proxy_d) (TypeQ -> TypeQ
proxyTypeQ TypeQ
t)
proxyPatQ :: TypeQ -> PatQ
proxyPatQ :: TypeQ -> PatQ
proxyPatQ TypeQ
t = forall (m :: * -> *). Quote m => m Pat -> m Type -> m Pat
sigP (forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP Name
proxy_d []) (TypeQ -> TypeQ
proxyTypeQ TypeQ
t)
pr :: QuasiQuoter
pr :: QuasiQuoter
pr = (String -> ExpQ)
-> (String -> PatQ)
-> (String -> TypeQ)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter (forall r. (TypeQ -> r) -> String -> r
mkProxy TypeQ -> ExpQ
proxyExpQ) (forall r. (TypeQ -> r) -> String -> r
mkProxy TypeQ -> PatQ
proxyPatQ) (forall r. (TypeQ -> r) -> String -> r
mkProxy TypeQ -> TypeQ
proxyTypeQ) forall a. HasCallStack => a
undefined where
mkProxy :: (TypeQ -> r) -> String -> r
mkProxy :: forall r. (TypeQ -> r) -> String -> r
mkProxy TypeQ -> r
p String
s = case [String]
ts of
[h :: String
h@(Char
t:String
_)]
| Char -> Bool
isUpper Char
t -> TypeQ -> r
p forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
head forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Q [Type]
cons
| Bool
otherwise -> TypeQ -> r
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). Quote m => Name -> m Type
varT forall a b. (a -> b) -> a -> b
$ String -> Name
mkName String
h
#if MIN_VERSION_template_haskell(2,8,0)
[String]
_ -> TypeQ -> r
p forall a b. (a -> b) -> a -> b
$ [Type] -> Type
mkList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Q [Type]
cons
#endif
where
ts :: [String]
ts = forall a b. (a -> b) -> [a] -> [b]
map String -> String
strip forall a b. (a -> b) -> a -> b
$ forall a. Eq a => a -> [a] -> [[a]]
splitOn Char
',' String
s
cons :: Q [Type]
cons = forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *). Quote m => Name -> m Type
conT forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Name
mkName) [String]
ts
#if MIN_VERSION_template_haskell(2,8,0)
mkList :: [Type] -> Type
mkList = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Type -> Type -> Type
AppT forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> Type -> Type
AppT Type
PromotedConsT) Type
PromotedNilT
#endif
#if MIN_VERSION_template_haskell(2,8,0)
pr1 :: QuasiQuoter
pr1 :: QuasiQuoter
pr1 = (String -> ExpQ)
-> (String -> PatQ)
-> (String -> TypeQ)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter (forall {f :: * -> *} {t}. Quote f => (f Type -> t) -> String -> t
mkProxy TypeQ -> ExpQ
proxyExpQ) (forall {f :: * -> *} {t}. Quote f => (f Type -> t) -> String -> t
mkProxy TypeQ -> PatQ
proxyPatQ) (forall {f :: * -> *} {t}. Quote f => (f Type -> t) -> String -> t
mkProxy TypeQ -> TypeQ
proxyTypeQ) forall a. HasCallStack => a
undefined where
sing :: Type -> Type
sing Type
x = Type -> Type -> Type
AppT (Type -> Type -> Type
AppT Type
PromotedConsT Type
x) Type
PromotedNilT
mkProxy :: (f Type -> t) -> String -> t
mkProxy f Type -> t
p String
s = case String
s of
Char
t:String
_
| Char -> Bool
isUpper Char
t -> f Type -> t
p (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Type -> Type
sing (forall (m :: * -> *). Quote m => Name -> m Type
conT forall a b. (a -> b) -> a -> b
$ String -> Name
mkName String
s))
| Bool
otherwise -> f Type -> t
p (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Type -> Type
sing (forall (m :: * -> *). Quote m => Name -> m Type
varT forall a b. (a -> b) -> a -> b
$ String -> Name
mkName String
s))
String
_ -> forall a. HasCallStack => String -> a
error String
"Empty string passed to pr1"
#endif
splitOn :: Eq a => a -> [a] -> [[a]]
splitOn :: forall a. Eq a => a -> [a] -> [[a]]
splitOn a
d = [a] -> [[a]]
go where
go :: [a] -> [[a]]
go [] = []
go [a]
xs = case [a]
t of
[] -> [[a]
h]
(a
_:[a]
t') -> [a]
h forall a. a -> [a] -> [a]
: [a] -> [[a]]
go [a]
t'
where ([a]
h,[a]
t) = forall a. (a -> Bool) -> [a] -> ([a], [a])
break (forall a. Eq a => a -> a -> Bool
== a
d) [a]
xs
strip :: String -> String
strip :: String -> String
strip = forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isSpace) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace