support auto-derive parameterized type

This commit is contained in:
Hideyuki Tanaka 2011-11-17 18:27:37 +09:00
parent 7869e96bac
commit 256da2124b
2 changed files with 44 additions and 18 deletions

View File

@ -22,14 +22,14 @@ import Data.MessagePack.Object
derivePack :: Name -> Q [Dec]
derivePack tyName = do
info <- reify tyName
case info of
TyConI (DataD _ {- cxt -} name _ {- tyVarBndr -} cons _ {- derivings -}) -> do
[d|
instance Packable $(conT name) where
put v = $(caseE [| v |] (map alt cons))
|]
d <- case info of
TyConI (DataD _ {- cxt -} name tyVars cons _ {- derivings -}) -> do
ds <- [d| put v = $(caseE [| v |] (map alt cons)) |]
instanceD (cx tyVars) (ct ''Packable name tyVars) $
map return ds
_ -> error $ "cant derive Packable: " ++ show tyName
return [d]
where
alt (NormalC conName elms) = do
@ -51,17 +51,18 @@ derivePack tyName = do
alt c = error $ "unsupported constructor: " ++ pprint c
deriveUnpack :: Name -> Q [Dec]
deriveUnpack tyName = do
info <- reify tyName
case info of
TyConI (DataD _ {- cxt -} name _ {- tyVarBndr -} cons _ {- derivings -}) -> do
[d|
instance Unpackable $(conT name) where
get = $(foldl1 (\x y -> [| $x `mplus` $y |]) $ map alt cons)
|]
d <- case info of
TyConI (DataD _ {- cxt -} name tyVars cons _ {- derivings -}) -> do
ds <- [d| get = $(foldl1 (\x y -> [| $x `mplus` $y |]) $ map alt cons) |]
instanceD (cx tyVars) (ct ''Unpackable name tyVars) $
map return ds
_ -> error $ "cant derive Packable: " ++ show tyName
_ -> error $ "cant derive Unpackable: " ++ show tyName
return [d]
where
alt (NormalC conName elms) = do
@ -85,11 +86,16 @@ deriveUnpack tyName = do
$(varE var) |]
deriveObject :: Name -> Q [Dec]
deriveObject typName = do
g <- derivePack typName
p <- deriveUnpack typName
o <- [d| instance OBJECT $(conT typName) where |]
return $ g ++ p ++ o
deriveObject tyName = do
g <- derivePack tyName
p <- deriveUnpack tyName
info <- reify tyName
o <- case info of
TyConI (DataD _ {- cxt -} name tyVars cons _ {- derivings -}) ->
-- use default implement
instanceD (cx tyVars) (ct ''OBJECT name tyVars) []
_ -> error $ "cant derive Object: " ++ show tyName
return $ g ++ p ++ [o]
failN Nothing = mzero
failN (Just a) =
@ -97,7 +103,18 @@ failN (Just a) =
Left _ -> mzero
Right v -> return v
cx tyVars =
cxt [ classP cl [varT tv]
| cl <- [''Packable, ''Unpackable, ''OBJECT]
, PlainTV tv <- tyVars ]
ct tc tyName tyVars =
appT (conT tc) $ foldl appT (conT tyName) $
map (\(PlainTV n) -> varT n) tyVars
key conName fname
| (prefix ++ "_") `isPrefixOf` sFname && length sFname > length prefix + 1 =
drop (length prefix + 1) sFname
| prefix `isPrefixOf` sFname && length sFname > length prefix =
uncapital $ drop (length prefix) sFname
| otherwise = sFname

View File

@ -22,6 +22,13 @@ data V
deriveObject ''V
data W a
= G a String
| H { hHoge :: Int, h_age :: a }
deriving (Show, Eq)
deriveObject ''W
test :: (OBJECT a, Show a, Eq a) => a -> IO ()
test v = do
let bs = pack v
@ -40,4 +47,6 @@ main = do
test $ D 3.14
test $ E "hello"
test $ F
test $ G (E "hello") "world"
test $ H 123 F
return ()