packages feed

geniplate 0.3.0.0 → 0.4.0.0

raw patch · 3 files changed

+65/−33 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Generics.Geniplate: transformBiM :: Name -> Q Exp
+ Data.Generics.Geniplate: transformBiMT :: [TypeQ] -> Name -> Q Exp

Files

Data/Generics/Geniplate.hs view
@@ -1,10 +1,12 @@ {-# LANGUAGE TemplateHaskell #-}-module Data.Generics.Geniplate(universeBi, universeBiT, transformBi, transformBiT) where+module Data.Generics.Geniplate(universeBi, universeBiT, transformBi, transformBiT, transformBiM, transformBiMT) where+import Control.Monad import Control.Exception(assert) import Control.Monad.State.Strict import Data.Maybe import Language.Haskell.TH import Language.Haskell.TH.Syntax hiding (lift)+import System.IO  -- | Generate TH code for a function that extracts all subparts of a certain type. -- The argument to 'universeBi' is a name with the type @S -> [T]@, for some types@@ -22,7 +24,7 @@     (ds, f) <- uniBiQ stops from to     x <- newName "_x"     let e = LamE [VarP x] $ LetE ds $ AppE (AppE f (VarE x)) (ListE [])---    qRunIO $ putStrLn $ pprint e+    qRunIO $ do putStrLn $ pprint e; hFlush stdout     return e  type U = StateT (Map Type Dec, Map Type Bool) Q@@ -95,6 +97,7 @@          TupleT _  -> fmap or $ mapM (contains to) ts          ArrowT    -> return False          ListT     -> contains to (head ts)+         VarT _    -> return False          t         -> genError $ "contains: unexpected type: " ++ pprint from ++ " (" ++ show t ++ ")"     modify $ \ (m, c) -> (m, mInsert from b c)     return b@@ -184,6 +187,7 @@     info <- qReify con     case info of         TyConI (DataD _ _ tvs cs _) -> return (tvs, cs)+        TyConI (NewtypeD _ _ tvs c _) -> return (tvs, [c])         PrimTyConI{} -> return ([], [])         i -> genError $ "unexpected TyCon: " ++ show i @@ -242,27 +246,41 @@ -- | Same as 'transformBi', but does not look inside any types mention in the -- list of types. transformBiT :: [TypeQ] -> Name -> Q Exp-transformBiT stops name = do+transformBiT = transformBiG False (id, AppE)++transformBiM :: Name -> Q Exp+transformBiM = transformBiMT []++transformBiMT :: [TypeQ] -> Name -> Q Exp+transformBiMT = transformBiG True (eret, eap)+  where eret e = AppE (VarE 'Control.Monad.return) e+        eap f a = AppE (AppE (VarE 'Control.Monad.ap) f) a++type RetAp = (Exp -> Exp, Exp -> Exp -> Exp)++transformBiG :: Bool -> RetAp -> [TypeQ] -> Name -> Q Exp+transformBiG monad ra stops name = do     (_tvs, fcn, res) <- getNameType name     f <- newName "_f"     (ds, tr) <-         case (fcn, res) of-            (AppT (AppT ArrowT s) s', AppT (AppT ArrowT t) t') | s == s' && t == t' -> trBiQ stops f s t+            (AppT (AppT ArrowT s) s', AppT (AppT ArrowT t) t') | not monad && s == s' && t == t' -> trBiQ ra stops f s t+            (AppT (AppT ArrowT s) (AppT m s'), AppT (AppT ArrowT t) (AppT m' t')) | monad && s == s' && t == t' && m == m' -> trBiQ ra stops f s t             _ -> genError $ "transformBi: malformed type: " ++ pprint (AppT (AppT ArrowT fcn) res) ++ ", should have form (S->S) -> (T->T)"     x <- newName "_x"     let e = LamE [VarP f, VarP x] $ LetE ds $ AppE tr (VarE x)---    qRunIO $ putStrLn $ pprint e+    qRunIO $ do putStrLn $ pprint e; hFlush stdout     return e -trBiQ :: [TypeQ] -> Name -> Type -> Type -> Q ([Dec], Exp)-trBiQ stops f aft st = do+trBiQ :: RetAp -> [TypeQ] -> Name -> Type -> Type -> Q ([Dec], Exp)+trBiQ ra stops f aft st = do     ss <- sequence stops     ft <- expandSyn aft-    (tr, (m, _)) <- runStateT (trBi (VarE f) ft st) (mEmpty, mFromList $ zip ss (repeat False))+    (tr, (m, _)) <- runStateT (trBi ra (VarE f) ft st) (mEmpty, mFromList $ zip ss (repeat False))     return (mElems m, tr) -trBi :: Exp -> Type -> Type -> U Exp-trBi f ft ast = do+trBi :: RetAp -> Exp -> Type -> Type -> U Exp+trBi ra f ft ast = do     (m, c) <- get     st <- lift $ expandSyn ast --    lift $ qRunIO $ print (ft, st)@@ -272,7 +290,7 @@             tr <- lift $ newName "_tr"             let mkRec = do                     put (mInsert st (FunD tr [Clause [] (NormalB $ TupE []) []]) m, c)  -- insert something to break recursion, will be replaced below.-                    trBiCase f ft st+                    trBiCase ra f ft st              cs <- if ft == st then do                       b <- contains' ft st@@ -296,45 +314,54 @@             modify $ \ (m', c') -> (mInsert st d m', c')             return $ VarE tr -trBiCase :: Exp -> Type -> Type -> U [Clause]-trBiCase f ft st = do+trBiCase :: RetAp -> Exp -> Type -> Type -> U [Clause]+trBiCase ra f ft st = do     let (con, ts) = splitTypeApp st     case con of-        ConT n    -> trBiCon f n ft ts-        TupleT _  -> trBiTuple f ft ts+        ConT n    -> trBiCon ra f n ft ts+        TupleT _  -> trBiTuple ra f ft ts --        ArrowT    -> lift $ fmap unFunD [d| f _ _r = _r |]           -- Stop at functions-        ListT     -> trBiList f ft (head ts)+        ListT     -> trBiList ra f ft (head ts)         _         -> genError $ "trBiCase: unexpected type: " ++ pprint st ++ " (" ++ show st ++ ")" -trBiList :: Exp -> Type -> Type -> U [Clause]-trBiList f ft st = do-    tr <- trBi f ft st-    rec <- trBi f ft (AppT ListT st)+trBiList :: RetAp -> Exp -> Type -> Type -> U [Clause]+trBiList ra f ft st = do+    nil <- trMkArm ra f ft [] (const $ ListP []) (ListE []) []+    cons <- trMkArm ra f ft [] (ConP '(:)) (ConE '(:)) [st, AppT ListT st]+    return [nil, cons]+{-+    tr <- trBi ra f ft st+    rec <- trBi ra f ft (AppT ListT st)     lift $ fmap unFunD [d| _f [] = []; _f (_x:_xs) = ($(return tr) _x) : ($(return rec) _xs) |]+-} -trBiTuple :: Exp -> Type -> [Type] -> U [Clause]-trBiTuple f ft ts = fmap (:[]) $ trMkArm f ft [] TupP TupE ts+trBiTuple :: RetAp -> Exp -> Type -> [Type] -> U [Clause]+trBiTuple ra f ft ts = do+    vs <- mapM (const $ lift $ newName "t") ts+    let tupE = LamE (map VarP vs) $ ListE (map VarE vs)+    c <- trMkArm ra f ft [] TupP tupE ts+    return [c] -trBiCon :: Exp -> Name -> Type -> [Type] -> U [Clause]-trBiCon f con ft ts = do+trBiCon :: RetAp -> Exp -> Name -> Type -> [Type] -> U [Clause]+trBiCon ra f con ft ts = do     (tvs, cons) <- lift $ getTyConInfo con-    let genArm (NormalC c xs) = arm (ConP c) (foldl AppE $ ConE c) xs-        genArm (InfixC x1 c x2) = arm (\ [p1, p2] -> InfixP p1 c p2) (\ [e1, e2] -> InfixE (Just e1) (ConE c) (Just e2)) [x1, x2]-        genArm (RecC c xs) = arm (ConP c) (foldl AppE $ ConE c) [ (b,t) | (_,b,t) <- xs ]+    let genArm (NormalC c xs) = arm (ConP c) (ConE c) xs+        genArm (InfixC x1 c x2) = arm (\ [p1, p2] -> InfixP p1 c p2) (ConE c) [x1, x2]+        genArm (RecC c xs) = arm (ConP c) (ConE c) [ (b,t) | (_,b,t) <- xs ]         genArm c = genError $ "trBiCon: " ++ show c         s = mkSubst tvs ts-        arm c ec xs = trMkArm f ft s c ec $ map snd xs+        arm c ec xs = trMkArm ra f ft s c ec $ map snd xs     mapM genArm cons -trMkArm :: Exp -> Type -> Subst -> ([Pat] -> Pat) -> ([Exp] -> Exp) -> [Type] -> U Clause-trMkArm f ft s c ec ts = do+trMkArm :: RetAp -> Exp -> Type -> Subst -> ([Pat] -> Pat) -> Exp -> [Type] -> U Clause+trMkArm ra@(ret, apl) f ft s c ec ts = do     vs <- mapM (const $ lift $ newName "_x") ts     let sub v t = do             let t' = subst s t-            tr <- trBi f ft t'+            tr <- trBi ra f ft t'             return $ AppE tr (VarE v)     es <- zipWithM sub vs ts-    let body = ec es+    let body = foldl apl (ret ec) es     return $ Clause [c (map VarP vs)] (NormalB body) []  
examples/Main.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE TemplateHaskell #-} module Main where+--import Control.Monad import Data.Generics.Geniplate  data T a = T { x :: Int, y :: a } deriving (Show)@@ -38,6 +39,8 @@ trans4 :: (B Char -> B Char) -> B Char -> B Char trans4 = $(transformBi 'trans4) +trans5 :: (Int -> Maybe Int) -> [Int] -> Maybe [Int]+trans5 = $(transformBiM 'trans5)  main :: IO () main = do@@ -53,3 +56,5 @@         f (Bin t1 x b t2) = Bin t1 x (not b) t2     print $ trans4 f $ tree 'a'     print $ uni5 [1,2]+    print $ trans5 Just [1,2,3]+    print $ trans5 (\ x -> if x==2 then Nothing else Just x) [1,2,3]
geniplate.cabal view
@@ -1,6 +1,6 @@ Name:           geniplate Cabal-Version:  >= 1.2-Version:        0.3.0.0+Version:        0.4.0.0 License:        BSD3 Author:         Lennart Augustsson Maintainer:     Lennart Augustsson