mirror of
https://github.com/khibino/haskell-relational-record.git
synced 2024-12-03 03:52:10 +03:00
relational-query: add ProductConstrustor instance template of tuple type.
This commit is contained in:
parent
872d09c58d
commit
f80e529096
@ -3,16 +3,16 @@
|
|||||||
|
|
||||||
module Database.Relational.Query.Internal.TH (
|
module Database.Relational.Query.Internal.TH (
|
||||||
defineProductConstructorInstance,
|
defineProductConstructorInstance,
|
||||||
|
defineTupleProductConstructor,
|
||||||
defineTuplePi,
|
defineTuplePi,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Applicative ((<$>))
|
import Control.Applicative ((<$>))
|
||||||
import Data.List (foldl')
|
import Data.List (foldl')
|
||||||
import Language.Haskell.TH
|
import Language.Haskell.TH
|
||||||
(Q, mkName, normalB, classP, varP,
|
(Q, Name, mkName, tupleDataName, normalB, classP, varP,
|
||||||
Exp,
|
TypeQ, forallT, arrowT, varT, tupleT, appT,
|
||||||
Type, forallT, varT, tupleT, appT, arrowT,
|
Dec, sigD, valD, ExpQ, conE,
|
||||||
Dec, sigD, valD,
|
|
||||||
TyVarBndr (PlainTV), )
|
TyVarBndr (PlainTV), )
|
||||||
import Database.Record.Persistable
|
import Database.Record.Persistable
|
||||||
(PersistableWidth, persistableWidth,
|
(PersistableWidth, persistableWidth,
|
||||||
@ -24,22 +24,32 @@ import Database.Relational.Query.Pi.Unsafe (Pi, definePi)
|
|||||||
|
|
||||||
|
|
||||||
-- | Make template for 'ProductConstructor' instance.
|
-- | Make template for 'ProductConstructor' instance.
|
||||||
defineProductConstructorInstance :: Q Type -> Q Exp -> [Q Type] -> Q [Dec]
|
defineProductConstructorInstance :: TypeQ -> ExpQ -> [TypeQ] -> Q [Dec]
|
||||||
defineProductConstructorInstance recTypeQ recData colTypes =
|
defineProductConstructorInstance recTypeQ recData colTypes =
|
||||||
[d| instance ProductConstructor $(foldr (appT . (arrowT `appT`)) recTypeQ colTypes) where
|
[d| instance ProductConstructor $(foldr (appT . (arrowT `appT`)) recTypeQ colTypes) where
|
||||||
productConstructor = $(recData)
|
productConstructor = $(recData)
|
||||||
|]
|
|]
|
||||||
|
|
||||||
-- | xxx
|
tupleN :: Int -> (([Name], [TypeQ]), TypeQ)
|
||||||
|
tupleN n = ((ns, vs), foldl' appT (tupleT n) vs)
|
||||||
|
where
|
||||||
|
ns = [ mkName $ "a" ++ show j | j <- [1 .. n] ]
|
||||||
|
vs = map varT ns
|
||||||
|
|
||||||
|
-- | Make template of ProductConstructor instance of tuple type.
|
||||||
|
defineTupleProductConstructor :: Int -> Q [Dec]
|
||||||
|
defineTupleProductConstructor n = do
|
||||||
|
let ((_, vs), tty) = tupleN n
|
||||||
|
defineProductConstructorInstance tty (conE $ tupleDataName n) vs
|
||||||
|
|
||||||
tuplePi :: Int -> Int -> Q [Dec]
|
tuplePi :: Int -> Int -> Q [Dec]
|
||||||
tuplePi n i = do
|
tuplePi n i = do
|
||||||
let selN = mkName $ "tuplePi" ++ show n ++ "_" ++ show i ++ "'"
|
let selN = mkName $ "tuplePi" ++ show n ++ "_" ++ show i ++ "'"
|
||||||
ns = [ mkName $ "a" ++ show j | j <- [1 .. n] ]
|
((ns, vs), tty) = tupleN n
|
||||||
vs = map varT ns
|
|
||||||
sig <- sigD selN $
|
sig <- sigD selN $
|
||||||
forallT (map PlainTV ns)
|
forallT (map PlainTV ns)
|
||||||
(mapM (classP ''PersistableWidth . (:[])) vs)
|
(mapM (classP ''PersistableWidth . (:[])) vs)
|
||||||
[t| Pi $(foldl' appT (tupleT n) vs) $(vs !! i) |]
|
[t| Pi $tty $(vs !! i) |]
|
||||||
val <- valD (varP selN)
|
val <- valD (varP selN)
|
||||||
(normalB [| definePi $(foldl'
|
(normalB [| definePi $(foldl'
|
||||||
(\e t -> [| $e + runPersistableRecordWidth (persistableWidth :: PersistableRecordWidth $t) |])
|
(\e t -> [| $e + runPersistableRecordWidth (persistableWidth :: PersistableRecordWidth $t) |])
|
||||||
|
Loading…
Reference in New Issue
Block a user