{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}
module Yesod.Core.Internal.TH where
import Prelude hiding (exp)
import Yesod.Core.Handler
import Language.Haskell.TH hiding (cxt, instanceD)
import Language.Haskell.TH.Syntax
import qualified Network.Wai as W
import Data.ByteString.Lazy.Char8 ()
import Data.List (foldl')
import Control.Monad (replicateM, void)
import Text.Parsec (parse, many1, many, eof, try, option, sepBy1)
import Text.ParserCombinators.Parsec.Char (alphaNum, spaces, string, char)
import Yesod.Routes.TH
import Yesod.Routes.Parse
import Yesod.Core.Types
import Yesod.Core.Class.Dispatch
import Yesod.Core.Internal.Run
mkYesod :: String
-> [ResourceTree String]
-> Q [Dec]
mkYesod :: String -> [ResourceTree String] -> Q [Dec]
mkYesod String
name = (([Dec], [Dec]) -> [Dec]) -> Q ([Dec], [Dec]) -> Q [Dec]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([Dec] -> [Dec] -> [Dec]) -> ([Dec], [Dec]) -> [Dec]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry [Dec] -> [Dec] -> [Dec]
forall a. [a] -> [a] -> [a]
(++)) (Q ([Dec], [Dec]) -> Q [Dec])
-> ([ResourceTree String] -> Q ([Dec], [Dec]))
-> [ResourceTree String]
-> Q [Dec]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String
-> Bool
-> (Exp -> Q Exp)
-> [ResourceTree String]
-> Q ([Dec], [Dec])
mkYesodWithParser String
name Bool
False Exp -> Q Exp
forall (m :: * -> *) a. Monad m => a -> m a
return
{-# DEPRECATED mkYesodWith "Contexts and type variables are now parsed from the name in `mkYesod`. <https://github.com/yesodweb/yesod/pull/1366>" #-}
mkYesodWith :: [[String]]
-> String
-> [String]
-> [ResourceTree String]
-> Q [Dec]
mkYesodWith :: [[String]]
-> String -> [String] -> [ResourceTree String] -> Q [Dec]
mkYesodWith [[String]]
cxts String
name [String]
args = (([Dec], [Dec]) -> [Dec]) -> Q ([Dec], [Dec]) -> Q [Dec]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([Dec] -> [Dec] -> [Dec]) -> ([Dec], [Dec]) -> [Dec]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry [Dec] -> [Dec] -> [Dec]
forall a. [a] -> [a] -> [a]
(++)) (Q ([Dec], [Dec]) -> Q [Dec])
-> ([ResourceTree String] -> Q ([Dec], [Dec]))
-> [ResourceTree String]
-> Q [Dec]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[String]]
-> String
-> [String]
-> Bool
-> (Exp -> Q Exp)
-> [ResourceTree String]
-> Q ([Dec], [Dec])
mkYesodGeneral [[String]]
cxts String
name [String]
args Bool
False Exp -> Q Exp
forall (m :: * -> *) a. Monad m => a -> m a
return
mkYesodData :: String -> [ResourceTree String] -> Q [Dec]
mkYesodData :: String -> [ResourceTree String] -> Q [Dec]
mkYesodData String
name [ResourceTree String]
resS = ([Dec], [Dec]) -> [Dec]
forall a b. (a, b) -> a
fst (([Dec], [Dec]) -> [Dec]) -> Q ([Dec], [Dec]) -> Q [Dec]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> Bool
-> (Exp -> Q Exp)
-> [ResourceTree String]
-> Q ([Dec], [Dec])
mkYesodWithParser String
name Bool
False Exp -> Q Exp
forall (m :: * -> *) a. Monad m => a -> m a
return [ResourceTree String]
resS
mkYesodSubData :: String -> [ResourceTree String] -> Q [Dec]
mkYesodSubData :: String -> [ResourceTree String] -> Q [Dec]
mkYesodSubData String
name [ResourceTree String]
resS = ([Dec], [Dec]) -> [Dec]
forall a b. (a, b) -> a
fst (([Dec], [Dec]) -> [Dec]) -> Q ([Dec], [Dec]) -> Q [Dec]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> Bool
-> (Exp -> Q Exp)
-> [ResourceTree String]
-> Q ([Dec], [Dec])
mkYesodWithParser String
name Bool
True Exp -> Q Exp
forall (m :: * -> *) a. Monad m => a -> m a
return [ResourceTree String]
resS
mkYesodWithParser :: String
-> Bool
-> (Exp -> Q Exp)
-> [ResourceTree String]
-> Q([Dec],[Dec])
mkYesodWithParser :: String
-> Bool
-> (Exp -> Q Exp)
-> [ResourceTree String]
-> Q ([Dec], [Dec])
mkYesodWithParser String
name Bool
isSub Exp -> Q Exp
f [ResourceTree String]
resS = do
let (String
name', [String]
rest, [[String]]
cxt) = case Parsec String () (String, [String], [[String]])
-> String
-> String
-> Either ParseError (String, [String], [[String]])
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
parse Parsec String () (String, [String], [[String]])
parseName String
"" String
name of
Left ParseError
err -> String -> (String, [String], [[String]])
forall a. HasCallStack => String -> a
error (String -> (String, [String], [[String]]))
-> String -> (String, [String], [[String]])
forall a b. (a -> b) -> a -> b
$ ParseError -> String
forall a. Show a => a -> String
show ParseError
err
Right (String, [String], [[String]])
a -> (String, [String], [[String]])
a
[[String]]
-> String
-> [String]
-> Bool
-> (Exp -> Q Exp)
-> [ResourceTree String]
-> Q ([Dec], [Dec])
mkYesodGeneral [[String]]
cxt String
name' [String]
rest Bool
isSub Exp -> Q Exp
f [ResourceTree String]
resS
where
parseName :: Parsec String () (String, [String], [[String]])
parseName = do
[[String]]
cxt <- [[String]]
-> ParsecT String () Identity [[String]]
-> ParsecT String () Identity [[String]]
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [] ParsecT String () Identity [[String]]
parseContext
String
name' <- ParsecT String () Identity String
forall u. ParsecT String u Identity String
parseWord
[String]
args <- ParsecT String () Identity String
-> ParsecT String () Identity [String]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity String
forall u. ParsecT String u Identity String
parseWord
ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
ParsecT String () Identity ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
(String, [String], [[String]])
-> Parsec String () (String, [String], [[String]])
forall (m :: * -> *) a. Monad m => a -> m a
return ( String
name', [String]
args, [[String]]
cxt)
parseWord :: ParsecT String u Identity String
parseWord = do
ParsecT String u Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
ParsecT String u Identity Char -> ParsecT String u Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String u Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
alphaNum
parseContext :: ParsecT String () Identity [[String]]
parseContext = ParsecT String () Identity [[String]]
-> ParsecT String () Identity [[String]]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String () Identity [[String]]
-> ParsecT String () Identity [[String]])
-> ParsecT String () Identity [[String]]
-> ParsecT String () Identity [[String]]
forall a b. (a -> b) -> a -> b
$ do
[[String]]
cxts <- ParsecT String () Identity [[String]]
-> ParsecT String () Identity [[String]]
forall s (m :: * -> *) u b.
Stream s m Char =>
ParsecT s u m b -> ParsecT s u m b
parseParen ParsecT String () Identity [[String]]
parseContexts
ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
String
_ <- String -> ParsecT String () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"=>"
[[String]] -> ParsecT String () Identity [[String]]
forall (m :: * -> *) a. Monad m => a -> m a
return [[String]]
cxts
parseParen :: ParsecT s u m b -> ParsecT s u m b
parseParen ParsecT s u m b
p = do
ParsecT s u m ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
Char
_ <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
b
r <- ParsecT s u m b
p
ParsecT s u m ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
Char
_ <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')'
b -> ParsecT s u m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
r
parseContexts :: ParsecT String () Identity [[String]]
parseContexts =
ParsecT String () Identity [String]
-> ParsecT String () Identity ()
-> ParsecT String () Identity [[String]]
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
sepBy1 (ParsecT String () Identity String
-> ParsecT String () Identity [String]
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String () Identity String
forall u. ParsecT String u Identity String
parseWord) (ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces ParsecT String () Identity ()
-> ParsecT String () Identity Char
-> ParsecT String () Identity Char
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
',' ParsecT String () Identity Char
-> ParsecT String () Identity () -> ParsecT String () Identity ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> ParsecT String () Identity ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())
mkYesodDispatch :: String -> [ResourceTree String] -> Q [Dec]
mkYesodDispatch :: String -> [ResourceTree String] -> Q [Dec]
mkYesodDispatch String
name = (([Dec], [Dec]) -> [Dec]) -> Q ([Dec], [Dec]) -> Q [Dec]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Dec], [Dec]) -> [Dec]
forall a b. (a, b) -> b
snd (Q ([Dec], [Dec]) -> Q [Dec])
-> ([ResourceTree String] -> Q ([Dec], [Dec]))
-> [ResourceTree String]
-> Q [Dec]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String
-> Bool
-> (Exp -> Q Exp)
-> [ResourceTree String]
-> Q ([Dec], [Dec])
mkYesodWithParser String
name Bool
False Exp -> Q Exp
forall (m :: * -> *) a. Monad m => a -> m a
return
masterTypeSyns :: [Name] -> Type -> [Dec]
masterTypeSyns :: [Name] -> Type -> [Dec]
masterTypeSyns [Name]
vs Type
site =
[ Name -> [TyVarBndr] -> Type -> Dec
TySynD (String -> Name
mkName String
"Handler") ((Name -> TyVarBndr) -> [Name] -> [TyVarBndr]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Name -> TyVarBndr
plainTV [Name]
vs)
(Type -> Dec) -> Type -> Dec
forall a b. (a -> b) -> a -> b
$ Name -> Type
ConT ''HandlerFor Type -> Type -> Type
`AppT` Type
site
, Name -> [TyVarBndr] -> Type -> Dec
TySynD (String -> Name
mkName String
"Widget") ((Name -> TyVarBndr) -> [Name] -> [TyVarBndr]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Name -> TyVarBndr
plainTV [Name]
vs)
(Type -> Dec) -> Type -> Dec
forall a b. (a -> b) -> a -> b
$ Name -> Type
ConT ''WidgetFor Type -> Type -> Type
`AppT` Type
site Type -> Type -> Type
`AppT` Name -> Type
ConT ''()
]
mkYesodGeneral :: [[String]]
-> String
-> [String]
-> Bool
-> (Exp -> Q Exp)
-> [ResourceTree String]
-> Q([Dec],[Dec])
mkYesodGeneral :: [[String]]
-> String
-> [String]
-> Bool
-> (Exp -> Q Exp)
-> [ResourceTree String]
-> Q ([Dec], [Dec])
mkYesodGeneral [[String]]
appCxt' String
namestr [String]
mtys Bool
isSub Exp -> Q Exp
f [ResourceTree String]
resS = do
let appCxt :: [Type]
appCxt = ([String] -> Type) -> [[String]] -> [Type]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(String
c:[String]
rest) ->
(Type -> String -> Type) -> Type -> [String] -> Type
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\Type
acc String
v -> Type
acc Type -> Type -> Type
`AppT` String -> Type
nameToType String
v) (Name -> Type
ConT (Name -> Type) -> Name -> Type
forall a b. (a -> b) -> a -> b
$ String -> Name
mkName String
c) [String]
rest
) [[String]]
appCxt'
Maybe Name
mname <- String -> Q (Maybe Name)
lookupTypeName String
namestr
Int
arity <- case Maybe Name
mname of
Just Name
name -> do
Info
info <- Name -> Q Info
reify Name
name
Int -> Q Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Q Int) -> Int -> Q Int
forall a b. (a -> b) -> a -> b
$
case Info
info of
TyConI Dec
dec ->
case Dec
dec of
DataD [Type]
_ Name
_ [TyVarBndr]
vs Maybe Type
_ [Con]
_ [DerivClause]
_ -> [TyVarBndr] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [TyVarBndr]
vs
NewtypeD [Type]
_ Name
_ [TyVarBndr]
vs Maybe Type
_ Con
_ [DerivClause]
_ -> [TyVarBndr] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [TyVarBndr]
vs
TySynD Name
_ [TyVarBndr]
vs Type
_ -> [TyVarBndr] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [TyVarBndr]
vs
Dec
_ -> Int
0
Info
_ -> Int
0
Maybe Name
_ -> Int -> Q Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
0
let name :: Name
name = String -> Name
mkName String
namestr
[Name]
vns <- Int -> Q Name -> Q [Name]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (Int
arity Int -> Int -> Int
forall a. Num a => a -> a -> a
- [String] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
mtys) (Q Name -> Q [Name]) -> Q Name -> Q [Name]
forall a b. (a -> b) -> a -> b
$ String -> Q Name
newName String
"t"
let argtypes :: [Type]
argtypes = (String -> Type) -> [String] -> [Type]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Type
nameToType [String]
mtys [Type] -> [Type] -> [Type]
forall a. [a] -> [a] -> [a]
++ (Name -> Type) -> [Name] -> [Type]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Name -> Type
VarT [Name]
vns
let argvars :: [Name]
argvars = ((String -> Name) -> [String] -> [Name]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Name
mkName ([String] -> [Name])
-> ([String] -> [String]) -> [String] -> [Name]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter String -> Bool
isTvar) [String]
mtys [Name] -> [Name] -> [Name]
forall a. [a] -> [a] -> [a]
++ [Name]
vns
let site :: Type
site = (Type -> Type -> Type) -> Type -> [Type] -> Type
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Type -> Type -> Type
AppT (Name -> Type
ConT Name
name) [Type]
argtypes
res :: [ResourceTree Type]
res = (ResourceTree String -> ResourceTree Type)
-> [ResourceTree String] -> [ResourceTree Type]
forall a b. (a -> b) -> [a] -> [b]
map ((String -> Type) -> ResourceTree String -> ResourceTree Type
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> Type
parseType (String -> Type) -> (String -> String) -> String -> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
dropBracket)) [ResourceTree String]
resS
[Dec]
renderRouteDec <- [Type] -> Type -> [ResourceTree Type] -> Q [Dec]
mkRenderRouteInstance [Type]
appCxt Type
site [ResourceTree Type]
res
Dec
routeAttrsDec <- [Type] -> Type -> [ResourceTree Type] -> Q Dec
forall a. [Type] -> Type -> [ResourceTree a] -> Q Dec
mkRouteAttrsInstance [Type]
appCxt Type
site [ResourceTree Type]
res
[Dec]
dispatchDec <- Type -> [Type] -> (Exp -> Q Exp) -> [ResourceTree Type] -> Q [Dec]
forall c.
Type -> [Type] -> (Exp -> Q Exp) -> [ResourceTree c] -> Q [Dec]
mkDispatchInstance Type
site [Type]
appCxt Exp -> Q Exp
f [ResourceTree Type]
res
Dec
parseRoute <- [Type] -> Type -> [ResourceTree Type] -> Q Dec
forall a. [Type] -> Type -> [ResourceTree a] -> Q Dec
mkParseRouteInstance [Type]
appCxt Type
site [ResourceTree Type]
res
let rname :: Name
rname = String -> Name
mkName (String -> Name) -> String -> Name
forall a b. (a -> b) -> a -> b
$ String
"resources" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
namestr
Exp
eres <- [ResourceTree String] -> Q Exp
forall t. Lift t => t -> Q Exp
lift [ResourceTree String]
resS
let resourcesDec :: [Dec]
resourcesDec =
[ Name -> Type -> Dec
SigD Name
rname (Type -> Dec) -> Type -> Dec
forall a b. (a -> b) -> a -> b
$ Type
ListT Type -> Type -> Type
`AppT` (Name -> Type
ConT ''ResourceTree Type -> Type -> Type
`AppT` Name -> Type
ConT ''String)
, Name -> [Clause] -> Dec
FunD Name
rname [[Pat] -> Body -> [Dec] -> Clause
Clause [] (Exp -> Body
NormalB Exp
eres) []]
]
let dataDec :: [Dec]
dataDec = [[Dec]] -> [Dec]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [Dec
parseRoute]
, [Dec]
renderRouteDec
, [Dec
routeAttrsDec]
, [Dec]
resourcesDec
, if Bool
isSub then [] else [Name] -> Type -> [Dec]
masterTypeSyns [Name]
argvars Type
site
]
([Dec], [Dec]) -> Q ([Dec], [Dec])
forall (m :: * -> *) a. Monad m => a -> m a
return ([Dec]
dataDec, [Dec]
dispatchDec)
mkMDS :: (Exp -> Q Exp) -> Q Exp -> MkDispatchSettings a site b
mkMDS :: (Exp -> Q Exp) -> Q Exp -> MkDispatchSettings a site b
mkMDS Exp -> Q Exp
f Q Exp
rh = MkDispatchSettings :: forall b site c.
Q Exp
-> Q Exp
-> Q Exp
-> Q Exp
-> Q Exp
-> Q Exp
-> Q Exp
-> (Maybe String -> String -> Q Exp)
-> (Exp -> Q Exp)
-> MkDispatchSettings b site c
MkDispatchSettings
{ mdsRunHandler :: Q Exp
mdsRunHandler = Q Exp
rh
, mdsSubDispatcher :: Q Exp
mdsSubDispatcher =
[|\parentRunner getSub toParent env -> yesodSubDispatch
YesodSubRunnerEnv
{ ysreParentRunner = parentRunner
, ysreGetSub = getSub
, ysreToParentRoute = toParent
, ysreParentEnv = env
}
|]
, mdsGetPathInfo :: Q Exp
mdsGetPathInfo = [|W.pathInfo|]
, mdsSetPathInfo :: Q Exp
mdsSetPathInfo = [|\p r -> r { W.pathInfo = p }|]
, mdsMethod :: Q Exp
mdsMethod = [|W.requestMethod|]
, mds404 :: Q Exp
mds404 = [|void notFound|]
, mds405 :: Q Exp
mds405 = [|void badMethod|]
, mdsGetHandler :: Maybe String -> String -> Q Exp
mdsGetHandler = Maybe String -> String -> Q Exp
defaultGetHandler
, mdsUnwrapper :: Exp -> Q Exp
mdsUnwrapper = Exp -> Q Exp
f
}
mkDispatchInstance :: Type
-> Cxt
-> (Exp -> Q Exp)
-> [ResourceTree c]
-> DecsQ
mkDispatchInstance :: Type -> [Type] -> (Exp -> Q Exp) -> [ResourceTree c] -> Q [Dec]
mkDispatchInstance Type
master [Type]
cxt Exp -> Q Exp
f [ResourceTree c]
res = do
Clause
clause' <- MkDispatchSettings Any Any Any -> [ResourceTree c] -> Q Clause
forall b site c a.
MkDispatchSettings b site c -> [ResourceTree a] -> Q Clause
mkDispatchClause ((Exp -> Q Exp) -> Q Exp -> MkDispatchSettings Any Any Any
forall a site b.
(Exp -> Q Exp) -> Q Exp -> MkDispatchSettings a site b
mkMDS Exp -> Q Exp
f [|yesodRunner|]) [ResourceTree c]
res
let thisDispatch :: Dec
thisDispatch = Name -> [Clause] -> Dec
FunD 'yesodDispatch [Clause
clause']
[Dec] -> Q [Dec]
forall (m :: * -> *) a. Monad m => a -> m a
return [[Type] -> Type -> [Dec] -> Dec
instanceD [Type]
cxt Type
yDispatch [Dec
thisDispatch]]
where
yDispatch :: Type
yDispatch = Name -> Type
ConT ''YesodDispatch Type -> Type -> Type
`AppT` Type
master
mkYesodSubDispatch :: [ResourceTree a] -> Q Exp
mkYesodSubDispatch :: [ResourceTree a] -> Q Exp
mkYesodSubDispatch [ResourceTree a]
res = do
Clause
clause' <- MkDispatchSettings Any Any Any -> [ResourceTree a] -> Q Clause
forall b site c a.
MkDispatchSettings b site c -> [ResourceTree a] -> Q Clause
mkDispatchClause ((Exp -> Q Exp) -> Q Exp -> MkDispatchSettings Any Any Any
forall a site b.
(Exp -> Q Exp) -> Q Exp -> MkDispatchSettings a site b
mkMDS Exp -> Q Exp
forall (m :: * -> *) a. Monad m => a -> m a
return [|subHelper|]) [ResourceTree a]
res
Name
inner <- String -> Q Name
newName String
"inner"
let innerFun :: Dec
innerFun = Name -> [Clause] -> Dec
FunD Name
inner [Clause
clause']
Name
helper <- String -> Q Name
newName String
"helper"
let fun :: Dec
fun = Name -> [Clause] -> Dec
FunD Name
helper
[ [Pat] -> Body -> [Dec] -> Clause
Clause
[]
(Exp -> Body
NormalB (Exp -> Body) -> Exp -> Body
forall a b. (a -> b) -> a -> b
$ Name -> Exp
VarE Name
inner)
[Dec
innerFun]
]
Exp -> Q Exp
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp -> Q Exp) -> Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$ [Dec] -> Exp -> Exp
LetE [Dec
fun] (Name -> Exp
VarE Name
helper)
instanceD :: Cxt -> Type -> [Dec] -> Dec
instanceD :: [Type] -> Type -> [Dec] -> Dec
instanceD = Maybe Overlap -> [Type] -> Type -> [Dec] -> Dec
InstanceD Maybe Overlap
forall a. Maybe a
Nothing