packages feed

geniplate-mirror 0.6.0.7 → 0.7

raw patch · 3 files changed

+158/−59 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Generics.Geniplate: class DescendBiM m s t
+ Data.Generics.Geniplate: class DescendM m t
+ Data.Generics.Geniplate: descend :: DescendM Identity a => (a -> a) -> (a -> a)
+ Data.Generics.Geniplate: descendBiM :: DescendBiM m s t => (s -> m s) -> t -> m t
+ Data.Generics.Geniplate: descendM :: DescendM m t => (t -> m t) -> t -> m t
+ Data.Generics.Geniplate: instance Eq Mode
+ Data.Generics.Geniplate: instance Ord Mode
+ Data.Generics.Geniplate: instance Show Mode
+ Data.Generics.Geniplate: instanceDescendBiM :: TypeQ -> TypeQ -> Q [Dec]
+ Data.Generics.Geniplate: instanceDescendBiMT :: [TypeQ] -> TypeQ -> TypeQ -> Q [Dec]
+ Data.Generics.Geniplate: instanceDescendM :: TypeQ -> TypeQ -> Q [Dec]
+ Data.Generics.Geniplate: instanceDescendMT :: [TypeQ] -> TypeQ -> TypeQ -> Q [Dec]

Files

Data/Generics/Geniplate.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, FlexibleInstances, TypeSynonymInstances, PatternGuards, CPP #-}+{-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, TypeSynonymInstances, PatternGuards, CPP, DoAndIfThenElse #-} module Data.Generics.Geniplate(     genUniverseBi, genUniverseBi', genUniverseBiT, genUniverseBiT',     genTransformBi, genTransformBi', genTransformBiT, genTransformBiT',@@ -6,14 +6,17 @@     UniverseBi(..), universe, instanceUniverseBi, instanceUniverseBiT,     TransformBi(..), transform, instanceTransformBi, instanceTransformBiT,     TransformBiM(..), transformM, instanceTransformBiM, instanceTransformBiMT,+    DescendBiM(..), instanceDescendBiM, instanceDescendBiMT,+    DescendM(..), descend, instanceDescendM, instanceDescendMT,     ) where import Control.Monad import Control.Exception(assert) import Control.Monad.State.Strict+import Control.Monad.Identity import Data.Maybe import Language.Haskell.TH import Language.Haskell.TH.Syntax hiding (lift)-import System.IO+--import System.IO  ---- Overloaded interface, same as Uniplate. @@ -29,6 +32,14 @@ class {-(Monad m) => -} TransformBiM m s t where     transformBiM :: (s -> m s) -> t -> m t +-- | Class for 'descendBiM'.+class {-(Monad m) => -} DescendBiM m s t where+    descendBiM :: (s -> m s) -> t -> m t++-- | Class for 'descendM'.+class {-(Monad m) => -} DescendM m t where+    descendM :: (t -> m t) -> t -> m t+ universe :: (UniverseBi a a) => a -> [a] universe = universeBi @@ -38,6 +49,9 @@ transformM :: (TransformBiM m a a) => (a -> m a) -> a -> m a transformM = transformBiM +descend :: (DescendM Identity a) => (a -> a) -> (a -> a)+descend f = runIdentity . descendM (return . f)+ ----  -- | Create a 'UniverseBi' instance.@@ -79,19 +93,48 @@ instanceTransformBiT :: [TypeQ]      -- ^types not touched by 'transformBi'                      -> TypeQ        -- ^(inner, outer) types                      -> Q [Dec]-instanceTransformBiT stops ty = instanceTransformBiT' stops =<< ty+instanceTransformBiT stops ty = instanceTransformBiT' MTransformBi stops =<< ty -instanceTransformBiT' :: [TypeQ] -> Type -> Q [Dec]-instanceTransformBiT' stops (ForallT _ _ t) = instanceTransformBiT' stops t-instanceTransformBiT' stops ty | (TupleT _, [ft, st]) <- splitTypeApp ty = do+data Mode = MTransformBi | MDescendBi | MDescend+    deriving (Eq, Ord, Show)++instanceTransformBiT' :: Mode -> [TypeQ] -> Type -> Q [Dec]+instanceTransformBiT' doDescend stops (ForallT _ _ t) = instanceTransformBiT' doDescend stops t+instanceTransformBiT' doDescend stops ty | (TupleT _, [ft, st]) <- splitTypeApp ty = do     f <- newName "_f"     x <- newName "_x"-    (ds, tr) <- trBiQ raNormal stops f ft st+    (ds, tr) <- trBiQ doDescend raNormal stops f ft st     let e = LamE [VarP f, VarP x] $ LetE ds $ AppE tr (VarE x)      return $ instDef ''TransformBi [ft, st] 'transformBi e-instanceTransformBiT' _ t = genError "instanceTransformBiT: the argument should be of the form [t| (S, T) |]"+instanceTransformBiT' _ _ t = genError "instanceTransformBiT: the argument should be of the form [t| (S, T) |]" +-- | Create a 'DescendBiM' instance.+instanceDescendM :: TypeQ+                     -> TypeQ+                     -> Q [Dec]+instanceDescendM = instanceDescendMT []++-- | Create a 'DescendBiM' instance with certain types being abstract.+instanceDescendMT :: [TypeQ]+                      -> TypeQ+                      -> TypeQ+                      -> Q [Dec]+instanceDescendMT stops mndq ty = instanceTransformBiMT' MDescend stops mndq =<< ty++-- | Create a 'DescendBiM' instance.+instanceDescendBiM :: TypeQ+                     -> TypeQ+                     -> Q [Dec]+instanceDescendBiM = instanceDescendBiMT []++-- | Create a 'DescendBiM' instance with certain types being abstract.+instanceDescendBiMT :: [TypeQ]+                      -> TypeQ+                      -> TypeQ+                      -> Q [Dec]+instanceDescendBiMT stops mndq ty = instanceTransformBiMT' MDescendBi stops mndq =<< ty+ -- | Create a 'TransformBiM' instance. instanceTransformBiM :: TypeQ                      -> TypeQ@@ -103,20 +146,30 @@                       -> TypeQ                       -> TypeQ                       -> Q [Dec]-instanceTransformBiMT stops mndq ty = instanceTransformBiMT' stops mndq =<< ty+instanceTransformBiMT stops mndq ty = instanceTransformBiMT' MTransformBi stops mndq =<< ty -instanceTransformBiMT' :: [TypeQ] -> TypeQ -> Type -> Q [Dec]-instanceTransformBiMT' stops mndq (ForallT _ _ t) = instanceTransformBiMT' stops mndq t-instanceTransformBiMT' stops mndq ty | (TupleT _, [ft, st]) <- splitTypeApp ty = do+instanceTransformBiMT' :: Mode -> [TypeQ] -> TypeQ -> Type -> Q [Dec]+instanceTransformBiMT' doDescend stops mndq (ForallT _ _ t) = instanceTransformBiMT' doDescend stops mndq t+instanceTransformBiMT'  MDescend stops mndq ty = do     mnd <- mndq      f <- newName "_f"     x <- newName "_x"-    (ds, tr) <- trBiQ raMonad stops f ft st+    (ds, tr) <- trBiQ MDescend raMonad stops f ty ty     let e = LamE [VarP f, VarP x] $ LetE ds $ AppE tr (VarE x)+    return $ instDef ''DescendM [mnd, ty] 'descendM e+instanceTransformBiMT' doDescend stops mndq ty | (TupleT _, [ft, st]) <- splitTypeApp ty = do+--    qRunIO $ do putStrLn "************"; hFlush stdout+    mnd <- mndq -    return $ instDef ''TransformBiM [mnd, ft, st] 'transformBiM e-instanceTransformBiMT' _ _ t = genError "instanceTransformBiMT: the argument should be of the form [t| (S, T) |]"+    f <- newName "_f"+    x <- newName "_x"+    (ds, tr) <- trBiQ doDescend raMonad stops f ft st+    let e = LamE [VarP f, VarP x] $ LetE ds $ AppE tr (VarE x)+        cls = case doDescend of MTransformBi -> ''TransformBiM; MDescendBi -> ''DescendBiM; MDescend -> error "MDescend"+        met = case doDescend of MTransformBi ->  'transformBiM; MDescendBi ->  'descendBiM; MDescend -> error "MDescend"+    return $ instDef cls [mnd, ft, st] met e+instanceTransformBiMT' _ _ _ t = genError "instanceTransformBiMT: the argument should be of the form [t| (S, T) |]"   -- | Generate TH code for a function that extracts all subparts of a certain type.@@ -139,6 +192,7 @@ genUniverseBiT' :: [TypeQ] -> TypeQ -> Q Exp genUniverseBiT' stops q = q >>= splitType >>= genUniverseBiTsplit stops +genUniverseBiTsplit :: [TypeQ] -> ([TyVarBndr], Type, Type) -> Q Exp genUniverseBiTsplit stops (_tvs,from,tos) = do     let to = unList tos --    qRunIO $ print (from, to)@@ -155,17 +209,26 @@     qReport b = lift . qReport b     qRecover = error "Data.Generics.Geniplate: qRecover not implemented"     qReify = lift . qReify-#if MIN_VERSION_template_haskell(2,7,0)+#if __GLASGOW_HASKELL__ >= 706     qReifyInstances n = lift . qReifyInstances n-#elif MIN_VERSION_template_haskell(2,5,0)+#elif __GLASGOW_HASKELL__ >= 702     qClassInstances n = lift . qClassInstances n #endif     qLocation = lift qLocation     qRunIO = lift . qRunIO-#if MIN_VERSION_template_haskell(2,7,0)+#if __GLASGOW_HASKELL__ >= 706     qLookupName ns = lift . qLookupName ns     qAddDependentFile = lift . qAddDependentFile+#if __GLASGOW_HASKELL__ >= 708+    qReifyRoles = lift . qReifyRoles+    qReifyAnnotations = lift . qReifyAnnotations+    qReifyModule = lift . qReifyModule+    qAddTopDecls = lift . qAddTopDecls+    qAddModFinalizer = lift . qAddModFinalizer+    qGetQ = undefined -- lift . qGetQ+    qPutQ = lift . qPutQ #endif+#endif  uniBiQ :: [TypeQ] -> Type -> Type -> Q ([Dec], Exp) uniBiQ stops from ato = do@@ -433,113 +496,135 @@ type RetAp = (Exp -> Exp, Exp -> Exp -> Exp, Exp -> Exp -> Exp)  transformBiG :: RetAp -> [TypeQ] -> Name -> Q Exp-transformBiG ra stops = getNameType >=> transformBiGsplit ra stops+transformBiG ra stops = getNameType >=> transformBiGsplit MTransformBi ra stops  transformBiG' :: RetAp -> [TypeQ] -> TypeQ -> Q Exp-transformBiG' ra stops q = q >>= splitType >>= transformBiGsplit ra stops+transformBiG' ra stops q = q >>= splitType >>= transformBiGsplit MTransformBi ra stops -transformBiGsplit ra stops (_tvs,fcn,res) = do+transformBiGsplit :: Mode -> RetAp -> [TypeQ] -> (t, Type, Type) -> Q Exp+transformBiGsplit doDescend ra stops (_tvs,fcn,res) = do     f <- newName "_f"     x <- newName "_x"     (ds, tr) <-         case (fcn, res) of-            (AppT (AppT ArrowT s) s',          AppT (AppT ArrowT t) t')           | s == s' && t == t'            -> trBiQ ra stops f s t-            (AppT (AppT ArrowT s) (AppT m s'), AppT (AppT ArrowT t) (AppT m' t')) | s == s' && t == t' && m == m' -> trBiQ ra stops f s t+            (AppT (AppT ArrowT s) s',          AppT (AppT ArrowT t) t')           | s == s' && t == t'            -> trBiQ doDescend ra stops f s t+            (AppT (AppT ArrowT s) (AppT m s'), AppT (AppT ArrowT t) (AppT m' t')) | s == s' && t == t' && m == m' -> trBiQ doDescend ra stops f s t             _ -> genError $ "transformBi: malformed type: " ++ pprint (AppT (AppT ArrowT fcn) res) ++ ", should have form (S->S) -> (T->T)"     let e = LamE [VarP f, VarP x] $ LetE ds $ AppE tr (VarE x) --    qRunIO $ do putStrLn $ pprint e; hFlush stdout     return e -trBiQ :: RetAp -> [TypeQ] -> Name -> Type -> Type -> Q ([Dec], Exp)-trBiQ ra stops f aft st = do+trBiQ :: Mode -> RetAp -> [TypeQ] -> Name -> Type -> Type -> Q ([Dec], Exp)+trBiQ doDescend ra stops f aft st = do     ss <- sequence stops     ft <- expandSyn aft-    (tr, (m, _)) <- runStateT (trBi ra (VarE f) ft st) (mEmpty, mFromList $ zip ss (repeat False))+    (tr, (m, _)) <- runStateT (trBi False doDescend ra (VarE f) ft st) (mEmpty, mFromList $ zip ss (repeat False))     return (mElems m, tr) -arrow :: Type -> Type -> Type-arrow t1 t2 = AppT (AppT ArrowT t1) t2+--arrow :: Type -> Type -> Type+--arrow t1 t2 = AppT (AppT ArrowT t1) t2 -trBi :: RetAp -> Exp -> Type -> Type -> U Exp-trBi ra@(ret, _, rbind) f ft ast = do+trBi :: Bool -> Mode -> RetAp -> Exp -> Type -> Type -> U Exp+--trBi True DescendBiM (ret, _, _) _ _ _ = return ret+trBi seenStop doDescend ra@(ret, _, rbind) f ft ast = do+--    qRunIO $ do print (seenStop, doDescend, ft, ast); hFlush stdout     (m, c) <- get     st <- expandSyn ast --    qRunIO $ print (ft, st)+{-+    if ft == st && seenStop && doDescend == MDescend then+      return f+     else+-}     case mLookup st m of-        Just (FunD n _) -> return $ VarE n+        Just (FunD n _) -> do+--            qRunIO $ print ("found", ft == st, seenStop, doDescend == MDescend)+            if doDescend == MDescend && ft == st then+                return f+             else+                return $ VarE n         _ -> do             tr <- qNewName "_tr"-            let mkRec = do+            let mkRec same = do+--                    qRunIO $ do putStrLn $ "mkRec " ++ show (same, tr); hFlush stdout                     put (mInsert st (FunD tr [Clause [] (NormalB $ TupE []) []]) m, c)  -- insert something to break recursion, will be replaced below.-                    trBiCase ra f ft st+                    trBiCase same doDescend ra f ft st              cs <- if ft == st then do                       b <- contains' ft st+--                      qRunIO $ do print ("equal", b, doDescend == MDescend, seenStop); hFlush stdout                       if b then do+--                          qRunIO $ do putStrLn "create g"; hFlush stdout                           g <- qNewName "_g"-                          gcs <- mkRec+                          gcs <- mkRec True                           let dg = FunD g gcs                           -- Insert with a dummy type, just to get the definition in the map for mElems.                           modify $ \ (m', c') -> (mInsert (ConT g) dg m', c')                           x <- qNewName "_x"-                          return [Clause [VarP x] (NormalB $ rbind f (AppE (VarE g) (VarE x))) []]+                          let f' = if doDescend == MDescend then id else rbind f+                          return [Clause [VarP x] (NormalB $ f' (AppE (VarE g) (VarE x))) []]                        else do+--                          qRunIO $ do putStrLn "call f"; hFlush stdout                           x <- qNewName "_x"                           return [Clause [VarP x] (NormalB $ AppE f (VarE x)) []]                   else do                       b <- contains ft st --                      qRunIO $ print (b, ft, st)                       if b then do-                          mkRec+                          mkRec False                        else do                           x <- qNewName "_x"                           return [Clause [VarP x] (NormalB $ ret $ VarE x) []]             let d = FunD tr cs-            modify $ \ (m', c') -> (mInsert st d m', c')+            modify $ \ (m', c') -> (mInsert st d m', c')  -- overwrite dummy binding from mkRec             return $ VarE tr -trBiCase :: RetAp -> Exp -> Type -> Type -> U [Clause]-trBiCase ra f ft st = do+trBiCase :: Bool -> Mode -> RetAp -> Exp -> Type -> Type -> U [Clause]+trBiCase seenStop doDescend ra f ft st = do     let (con, ts) = splitTypeApp st     case con of-        ConT n    -> trBiCon ra f n ft st ts-        TupleT _  -> trBiTuple ra f ft st ts+        ConT n    -> trBiCon seenStop doDescend ra f n ft st ts+        TupleT _  -> trBiTuple seenStop doDescend ra f ft st ts --        ArrowT    -> unFun [d| f _ _r = _r |]           -- Stop at functions-        ListT     -> trBiList ra f ft st (head ts)+        ListT     -> trBiList seenStop doDescend ra f ft st (head ts)         _         -> genError $ "trBiCase: unexpected type: " ++ pprint st ++ " (" ++ show st ++ ")" -trBiList :: RetAp -> Exp -> Type -> Type -> Type -> U [Clause]-trBiList ra f ft st et = do-    nil <- trMkArm ra f ft st [] (const $ ListP []) (ListE []) []-    cons <- trMkArm ra f ft st [] (ConP '(:)) (ConE '(:)) [et, st]+trBiList :: Bool -> Mode -> RetAp -> Exp -> Type -> Type -> Type -> U [Clause]+trBiList seenStop doDescend ra f ft st et = do+    nil <- trMkArm seenStop doDescend ra f ft st [] (const $ ListP []) (ListE []) []+    cons <- trMkArm seenStop doDescend ra f ft st [] (ConP '(:)) (ConE '(:)) [et, st]     return [nil, cons] -trBiTuple :: RetAp -> Exp -> Type -> Type -> [Type] -> U [Clause]-trBiTuple ra f ft st ts = do+trBiTuple :: Bool -> Mode -> RetAp -> Exp -> Type -> Type -> [Type] -> U [Clause]+trBiTuple seenStop doDescend ra f ft st ts = do     vs <- mapM (const $ qNewName "_t") ts     let tupE = LamE (map VarP vs) $ TupE (map VarE vs)-    c <- trMkArm ra f ft st [] TupP tupE ts+    c <- trMkArm seenStop doDescend ra f ft st [] TupP tupE ts     return [c] -trBiCon :: RetAp -> Exp -> Name -> Type -> Type -> [Type] -> U [Clause]-trBiCon ra f con ft st ts = do+trBiCon :: Bool -> Mode -> RetAp -> Exp -> Name -> Type -> Type -> [Type] -> U [Clause]+trBiCon seenStop doDescend ra f con ft st ts = do     (tvs, cons) <- getTyConInfo con     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 ra f ft st s c ec $ map snd xs+        arm c ec xs = trMkArm seenStop doDescend ra f ft st s c ec $ map snd xs     mapM genArm cons -trMkArm :: RetAp -> Exp -> Type -> Type -> Subst -> ([Pat] -> Pat) -> Exp -> [Type] -> U Clause-trMkArm ra@(ret, apl, _) f ft st s c ec ts = do+trMkArm :: Bool -> Mode -> RetAp -> Exp -> Type -> Type -> Subst -> ([Pat] -> Pat) -> Exp -> [Type] -> U Clause+trMkArm seenStop doDescend ra@(ret, apl, _) f ft st s c ec ts = do     vs <- mapM (const $ qNewName "_x") ts     let sub v t = do-            let t' = subst s t-            tr <- trBi ra f ft t'-            return $ AppE tr (VarE v)-        conTy = foldr arrow st (map (subst s) ts)+--            qRunIO $ print ("put", seenStop, doDescend, ft == st)+            if seenStop && doDescend == MDescendBi then do+                return $ ret (VarE v)+            else do+                let t' = subst s t+                tr <- trBi seenStop doDescend ra f ft t'+                return $ AppE tr (VarE v)+--        conTy = foldr arrow st (map (subst s) ts)     es <- zipWithM sub vs ts     let body = foldl apl (ret ec) es     return $ Clause [c (map VarP vs)] (NormalB body) []
+ changelog view
@@ -0,0 +1,13 @@+geniplate 0.7 (released 2015-06-02):+* Add descend, DescendM and DescendBiM.+  Related pull request: https://github.com/augustss/geniplate/pull/7++geniplate 0.6.0.7 (released 2015-05-25):++* Blocking polymorphic type constructors in `transformBiM'` and families.+  Contributed by Nick Smallbone.++geniplate 0.6.0.6 (relased 2015-04-29):+* Support GHC 7.10+* Add TypeQ-arg'd versions of `genUniverseBi*` and `genTransformBi*`+  Contributed by Víctor López Juan.
geniplate-mirror.cabal view
@@ -1,5 +1,5 @@ Name:           geniplate-mirror-Version:        0.6.0.7+Version:        0.7 Synopsis:       Use Template Haskell to generate Uniplate-like functions. Description:    Use Template Haskell to generate Uniplate-like functions.                 .@@ -21,6 +21,7 @@ Extra-source-files:   examples/Main.hs   examples/output+  changelog  source-repository head   type:     git