@@ -1,44 +1,81 @@
1{-# LANGUAGE TemplateHaskell #-}
1{-# LANGUAGE TemplateHaskell #-}
2module Control.Ether.TH
2module Control.Ether.TH
3− ( etherealReader
3+ ( ethereal
5+ , defaultEtherealReaderConfig
6import qualified Language.Haskell.TH as TH
8import qualified Language.Haskell.TH as TH
8import Data.Proxy
10import Data.Proxy
11+import Data.Functor.Identity
9import Control.Ether.Core
12import Control.Ether.Core
10import Control.Monad.Ether.Reader
13import Control.Monad.Ether.Reader
12emptyDataDecl :: TH.Name -> TH.DecQ
15emptyDataDecl :: TH.Name -> TH.DecQ
13emptyDataDecl name = TH.dataD (return []) name [] [] []
16emptyDataDecl name = TH.dataD (return []) name [] [] []
15−etherealReader :: String -> String -> String -> TH.Name -> TH.DecsQ
18+funSimple :: TH.Name -> TH.ExpQ -> TH.DecQ
19+funSimple name body = TH.funD name [ TH.clause [] (TH.normalB body) [] ]
21+tyVar :: String -> TH.Q (TH.TyVarBndr, TH.TypeQ)
23+ thName <- TH.newName name
24+ let thType = TH.varT thName
25+ return (TH.PlainTV thName, thType)
28+ = EtherealReaderConfig TH.Name String String String String String
30+defaultEtherealReaderConfig :: TH.Name -> String -> EtherealConfig
31+defaultEtherealReaderConfig tyname name = EtherealReaderConfig
35+ ("run" ++ name ++ "T")
39+ethereal :: EtherealConfig -> TH.DecsQ
41+ethereal (EtherealReaderConfig
43+ strTagName strRunTransName
16−etherealReader strTagName strRunName strAskName tyname = do
44+ strRunName strAskName) = do
45+ let effName = TH.mkName strEffName
17− let tagName = TH.mkName strTagName
46+ tagName = TH.mkName strTagName
18 tag = TH.conT tagName
47 tag = TH.conT tagName
48+ runTransName = TH.mkName strRunTransName
19 runName = TH.mkName strRunName
49 runName = TH.mkName strRunName
20 askName = TH.mkName strAskName
50 askName = TH.mkName strAskName
51+ effDecl <- TH.tySynD effName [] [t| MonadEtherReader $tag |]
21 tagDecl <- emptyDataDecl tagName
52 tagDecl <- emptyDataDecl tagName
22 [tagInst] <- [d| type instance EtherData $tag = $(TH.conT tyname) |]
53 [tagInst] <- [d| type instance EtherData $tag = $(TH.conT tyname) |]
55+ (mBndr, m) <- tyVar "m"
56+ (aBndr, a) <- tyVar "a"
58+ $ TH.forallT [mBndr, aBndr] (return [])
59+ [t| EtherReaderT $tag $m $a -> EtherData $tag -> $m $a |]
60+ runTransFunBody <- funSimple runTransName
61+ [e| runEtherReaderT (Proxy :: Proxy $tag) |]
23 runFunSig <- do
62 runFunSig <- do
24− mName <- TH.newName "m"
63+ (aBndr, a) <- tyVar "a"
25− aName <- TH.newName "a"
64+ TH.sigD runName
26− let m' = TH.varT mName
65+ $ TH.forallT [aBndr] (return [])
28− ty = TH.forallT [TH.PlainTV mName, TH.PlainTV aName] (return [])
29− [t| EtherReaderT $tag $m' $a' -> EtherData $tag -> $m' $a' |]
66+ [t| EtherReaderT $tag Identity $a -> EtherData $tag -> $a |]
31− runFunBody <-
67+ runFunBody <- funSimple runName
32− let body = [e| runEtherReaderT (Proxy :: Proxy $tag) |]
68+ [e| ((runIdentity.).) $(TH.varE runTransName) |]
33− in TH.funD runName [ TH.clause [] (TH.normalB body) [] ]
34 askFunSig <- do
69 askFunSig <- do
35− mName <- TH.newName "m"
70+ (mBndr, m) <- tyVar "m"
36− let m' = TH.varT mName
71+ TH.sigD askName
37− ty = TH.forallT [TH.PlainTV mName]
72+ $ TH.forallT [mBndr]
38− (sequence [ [t| MonadEtherReader $tag $m' |] ])
73+ (sequence [ [t| MonadEtherReader $tag $m |] ])
39− [t| $m' (EtherData $tag) |]
74+ [t| $m (EtherData $tag) |]
41 askFunBody <-
75 askFunBody <-
42 let body = [e| etherAsk (Proxy :: Proxy $tag) |]
76 let body = [e| etherAsk (Proxy :: Proxy $tag) |]
43 in TH.funD askName [ TH.clause [] (TH.normalB body) [] ]
77 in TH.funD askName [ TH.clause [] (TH.normalB body) [] ]
78+ return [ effDecl, tagDecl, tagInst
79+ , runTransFunSig, runTransFunBody
44− return [ tagDecl, tagInst, runFunSig, runFunBody, askFunSig, askFunBody ]
80+ , runFunSig, runFunBody
81+ , askFunSig, askFunBody ]