packages feed

geniplate 0.4.0.1 → 0.5.0.0

raw patch · 3 files changed

+167/−125 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.Generics.Geniplate: transformBiMT :: [TypeQ] -> Name -> Q Exp
- Data.Generics.Geniplate: transformBiT :: [TypeQ] -> Name -> Q Exp
- Data.Generics.Geniplate: universeBiT :: [TypeQ] -> Name -> Q Exp
+ Data.Generics.Geniplate: class TransformBi s t
+ Data.Generics.Geniplate: class TransformBiM m s t
+ Data.Generics.Geniplate: class UniverseBi s t
+ Data.Generics.Geniplate: genTransformBi :: Name -> Q Exp
+ Data.Generics.Geniplate: genTransformBiM :: Name -> Q Exp
+ Data.Generics.Geniplate: genTransformBiMT :: [TypeQ] -> Name -> Q Exp
+ Data.Generics.Geniplate: genTransformBiT :: [TypeQ] -> Name -> Q Exp
+ Data.Generics.Geniplate: genUniverseBi :: Name -> Q Exp
+ Data.Generics.Geniplate: genUniverseBiT :: [TypeQ] -> Name -> Q Exp
+ Data.Generics.Geniplate: instanceTransformBi :: TypeQ -> TypeQ -> Q [Dec]
+ Data.Generics.Geniplate: instanceTransformBiM :: TypeQ -> TypeQ -> TypeQ -> Q [Dec]
+ Data.Generics.Geniplate: instanceTransformBiMT :: [TypeQ] -> TypeQ -> TypeQ -> TypeQ -> Q [Dec]
+ Data.Generics.Geniplate: instanceTransformBiT :: [TypeQ] -> TypeQ -> TypeQ -> Q [Dec]
+ Data.Generics.Geniplate: instanceUniverseBi :: TypeQ -> TypeQ -> Q [Dec]
+ Data.Generics.Geniplate: instanceUniverseBiT :: [TypeQ] -> TypeQ -> TypeQ -> Q [Dec]
+ Data.Generics.Geniplate: transform :: TransformBi a a => (a -> a) -> a -> a
+ Data.Generics.Geniplate: transformM :: TransformBiM m a a => (a -> m a) -> a -> m a
+ Data.Generics.Geniplate: universe :: UniverseBi a a => a -> [a]
- Data.Generics.Geniplate: transformBi :: Name -> Q Exp
+ Data.Generics.Geniplate: transformBi :: TransformBi s t => (s -> s) -> t -> t
- Data.Generics.Geniplate: transformBiM :: Name -> Q Exp
+ Data.Generics.Geniplate: transformBiM :: TransformBiM m s t => (s -> m s) -> t -> m t
- Data.Generics.Geniplate: universeBi :: Name -> Q Exp
+ Data.Generics.Geniplate: universeBi :: UniverseBi s t => s -> [t]

Files

Data/Generics/Geniplate.hs view
@@ -1,5 +1,12 @@-{-# LANGUAGE TemplateHaskell #-}-module Data.Generics.Geniplate(universeBi, universeBiT, transformBi, transformBiT, transformBiM, transformBiMT) where+{-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, FlexibleInstances #-}+module Data.Generics.Geniplate(+    genUniverseBi, genUniverseBiT,+    genTransformBi, genTransformBiT,+    genTransformBiM, genTransformBiMT,+    UniverseBi(..), universe, instanceUniverseBi, instanceUniverseBiT,+    TransformBi(..), transform, instanceTransformBi, instanceTransformBiT,+    TransformBiM(..), transformM, instanceTransformBiM, instanceTransformBiMT,+    ) where import Control.Monad import Control.Exception(assert) import Control.Monad.State.Strict@@ -8,16 +15,78 @@ import Language.Haskell.TH.Syntax hiding (lift) import System.IO +class UniverseBi s t where+    universeBi :: s -> [t]++class TransformBi s t where+    transformBi :: (s -> s) -> t -> t++class {-(Monad m) => -} TransformBiM m s t where+    transformBiM :: (s -> m s) -> t -> m t++universe :: (UniverseBi a a) => a -> [a]+universe = universeBi++transform :: (TransformBi a a) => (a -> a) -> a -> a+transform = transformBi++transformM :: (TransformBiM m a a) => (a -> m a) -> a -> m a+transformM = transformBiM+++instanceUniverseBi :: TypeQ -> TypeQ -> Q [Dec]+instanceUniverseBi = instanceUniverseBiT []++instanceUniverseBiT :: [TypeQ] -> TypeQ -> TypeQ -> Q [Dec]+instanceUniverseBiT stops fromq toq = do+    from <- fromq+    to <- toq+    (ds, f) <- uniBiQ stops from to+    x <- newName "_x"+    let e = LamE [VarP x] $ LetE ds $ AppE (AppE f (VarE x)) (ListE [])+    [d|instance UniverseBi $fromq $toq where universeBi = $(return e) |]++instanceTransformBi :: TypeQ -> TypeQ -> Q [Dec]+instanceTransformBi = instanceTransformBiT []++instanceTransformBiT :: [TypeQ] -> TypeQ -> TypeQ -> Q [Dec]+instanceTransformBiT stops ftq stq = do+    ft <- ftq+    st <- stq++    f <- newName "_f"+    x <- newName "_x"+    (ds, tr) <- trBiQ raNormal stops f ft st+    let e = LamE [VarP f, VarP x] $ LetE ds $ AppE tr (VarE x)++    [d|instance TransformBi $ftq $stq where transformBi = $(return e) |]++instanceTransformBiM :: TypeQ -> TypeQ -> TypeQ -> Q [Dec]+instanceTransformBiM = instanceTransformBiMT []++instanceTransformBiMT :: [TypeQ] -> TypeQ -> TypeQ -> TypeQ -> Q [Dec]+instanceTransformBiMT stops mndq ftq stq = do+    ft <- ftq+    st <- stq++    f <- newName "_f"+    x <- newName "_x"+    (ds, tr) <- trBiQ raMonad stops f ft st+    let e = LamE [VarP f, VarP x] $ LetE ds $ AppE tr (VarE x)++    [d|instance TransformBiM $mndq $ftq $stq where transformBiM = $(return e) |]++ -- | 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+-- The argument to 'genUniverseBi' is a name with the type @S -> [T]@, for some types -- @S@ and @T@.  The function will extract all subparts of type @T@ from @S@.-universeBi :: Name -> Q Exp-universeBi = universeBiT []+genUniverseBi :: Name -> Q Exp+genUniverseBi = genUniverseBiT [] --- | Same as 'universeBi', but does not look inside any types mention in the+-- | Same as 'genUniverseBi', but does not look inside any types mention in the -- list of types.-universeBiT :: [TypeQ] -> Name -> Q Exp-universeBiT stops name = do+genUniverseBiT :: [TypeQ] -> Name -> Q Exp+genUniverseBiT stops name = do     (_tvs, from, tos) <- getNameType name     let to = unList tos --    qRunIO $ print (from, to)@@ -27,31 +96,28 @@ --    qRunIO $ do putStrLn $ pprint e; hFlush stdout     return e -type U = StateT (Integer, Map Type [Dec], Map Type Bool) Q+type U = StateT (Map Type Dec, Map Type Bool) Q  newNameU :: String -> U Name-newNameU s = do-    (n, m, c) <- get-    put (n+1, m, c)-    lift $ newName $ s ++ "_" ++ show n+newNameU s = lift $ newName s  uniBiQ :: [TypeQ] -> Type -> Type -> Q ([Dec], Exp) uniBiQ stops from ato = do     ss <- sequence stops     to <- expandSyn ato-    (f, (_, m, _)) <- runStateT (uniBi from to) (0, mEmpty, mFromList $ zip ss (repeat False))-    return (concat $ mElems m, f)+    (f, (m, _)) <- runStateT (uniBi from to) (mEmpty, mFromList $ zip ss (repeat False))+    return (mElems m, f)  uniBi :: Type -> Type -> U Exp uniBi afrom to = do-    (n, m, c) <- get+    (m, c) <- get     from <- lift $ expandSyn afrom     case mLookup from m of-        Just (FunD n _ : _) -> return $ VarE n+        Just (FunD n _) -> return $ VarE n         _ -> do             f <- newNameU "_f"             let mkRec = do-                    put (n, mInsert from [FunD f [Clause [] (NormalB $ TupE []) []]] m, c)   -- insert something to break recursion, will be replaced below.+                    put (mInsert from (FunD f [Clause [] (NormalB $ TupE []) []]) m, c)   -- insert something to break recursion, will be replaced below.                     uniBiCase from to             cs <- if from == to then do                       b <- contains' to from@@ -59,9 +125,9 @@                           -- Recursive data type, we need the current value and all values inside.                           g <- newNameU "_g"                           gcs <- mkRec-                          let dg = [FunD g gcs]+                          let dg = FunD g gcs                           -- Insert with a dummy type, just to get the definition in the map for mElems.-                          modify $ \ (n', m', c') -> (n', mInsert (ConT g) dg m', c')+                          modify $ \ (m', c') -> (mInsert (ConT g) dg m', c')                           lift $ fmap unFunD [d| f _x _r = _x : $(return (VarE g)) _x _r |]                        else                           -- Non-recursive type, just use this value.@@ -75,8 +141,8 @@                        else                           -- No occurrences of to inside from, so add nothing.                           lift $ fmap unFunD [d| f _ _r = _r |]-            let d = [FunD f cs]-            modify $ \ (n', m', c') -> (n', mInsert from d m', c')+            let d = FunD f cs+            modify $ \ (m', c') -> (mInsert from d m', c')             return $ VarE f  -- Check if the second type is contained anywhere in the first type.@@ -87,7 +153,7 @@     if from == to then         return True      else do-        c <- gets (\ (_,_,c) -> c)+        c <- gets snd         case mLookup from c of             Just b  -> return b             Nothing -> contains' to from@@ -97,15 +163,15 @@ contains' to from = do --    lift $ qRunIO $ print ("contains'", to, from)     let (con, ts) = splitTypeApp from-    modify $ \ (n, m, c) -> (n, m, mInsert from False c)        -- To make the fixpoint of the recursion False.+    modify $ \ (m, c) -> (m, mInsert from False c)        -- To make the fixpoint of the recursion False.     b <- case con of          ConT n    -> containsCon n to ts          TupleT _  -> fmap or $ mapM (contains to) ts          ArrowT    -> return False-         ListT     -> contains to (head ts)+         ListT     -> if to == from then return True else contains to (head ts)          VarT _    -> return False          t         -> genError $ "contains: unexpected type: " ++ pprint from ++ " (" ++ show t ++ ")"-    modify $ \ (n, m, c) -> (n, m, mInsert from b c)+    modify $ \ (m, c) -> (m, mInsert from b c)     return b  containsCon :: Name -> Type -> [Type] -> U Bool@@ -225,6 +291,7 @@  expandSynApp :: Type -> [Type] -> Q Type expandSynApp (AppT t1 t2) ts = do t2' <- expandSyn t2; expandSynApp t1 (t2':ts)+expandSynApp (ConT n) ts | nameBase n == "[]" = return $ foldl AppT ListT ts expandSynApp t@(ConT n) ts = do     info <- qReify n     case info of@@ -244,76 +311,78 @@  -- Exp has type (S -> S) -> T -> T, for some S and T -- | Generate TH code for a function that transforms all subparts of a certain type.--- The argument to 'transformBi' is a name with the type @(S->S) -> T -> T@, for some types+-- The argument to 'genTransformBi' is a name with the type @(S->S) -> T -> T@, for some types -- @S@ and @T@.  The function will transform all subparts of type @S@ inside @T@ using the given function.-transformBi :: Name -> Q Exp-transformBi = transformBiT []+genTransformBi :: Name -> Q Exp+genTransformBi = genTransformBiT [] --- | Same as 'transformBi', but does not look inside any types mention in the+-- | Same as 'genTransformBi', but does not look inside any types mention in the -- list of types.-transformBiT :: [TypeQ] -> Name -> Q Exp-transformBiT = transformBiG (Nothing, id, AppE, AppE)+genTransformBiT :: [TypeQ] -> Name -> Q Exp+genTransformBiT = transformBiG raNormal -transformBiM :: Name -> Q Exp-transformBiM = transformBiMT []+raNormal :: RetAp+raNormal = (id, AppE, AppE) -transformBiMT :: [TypeQ] -> Name -> Q Exp-transformBiMT = transformBiG (Just undefined, eret, eap, emap)+genTransformBiM :: Name -> Q Exp+genTransformBiM = genTransformBiMT []++genTransformBiMT :: [TypeQ] -> Name -> Q Exp+genTransformBiMT = transformBiG raMonad++raMonad :: RetAp+raMonad = (eret, eap, emap)   where eret e = AppE (VarE 'Control.Monad.return) e         eap f a = AppE (AppE (VarE 'Control.Monad.ap) f) a         emap f a = AppE (AppE (VarE '(Control.Monad.=<<)) f) a -type RetAp = (Maybe Type, Exp -> Exp, Exp -> Exp -> Exp, Exp -> Exp -> Exp)+type RetAp = (Exp -> Exp, Exp -> Exp -> Exp, Exp -> Exp -> Exp)  transformBiG :: RetAp -> [TypeQ] -> Name -> Q Exp transformBiG ra stops name = do     (_tvs, fcn, res) <- getNameType name     f <- newName "_f"     x <- newName "_x"-    (ds, tr, fty, argty) <--        case (ra, fcn, res) of-            ((Nothing,_,_,_),     AppT (AppT ArrowT s) s',          AppT (AppT ArrowT t) t') | s == s' && t == t' -> trBiQ ra stops f s t-            ((Just _,ret, apl, rbn), AppT (AppT ArrowT s) (AppT m s'), AppT (AppT ArrowT t) (AppT m' t')) |-                      s == s' && t == t' && m == m' -> trBiQ (Just m, ret, apl, rbn) stops f s t+    (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             _ -> genError $ "transformBi: malformed type: " ++ pprint (AppT (AppT ArrowT fcn) res) ++ ", should have form (S->S) -> (T->T)"-    let e = LamE [VarP f {-`SigP` fty-}, VarP x {-`SigP` argty-}] $ LetE ds $ AppE tr (VarE x)+    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, Type, Type)-trBiQ ra@(mty,_,_,_) 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 ra (VarE f) ft st) (0, mEmpty, mFromList $ zip ss (repeat False))-    let fty = ft `arrow` maybe ft (flip AppT ft) mty-    return (concat $ mElems m, tr, fty, st)+    (tr, (m, _)) <- runStateT (trBi 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  trBi :: RetAp -> Exp -> Type -> Type -> U Exp-trBi ra@(mty, ret, _, rbind) f ft ast = do-    (n, m, c) <- get+trBi ra@(ret, _, rbind) f ft ast = do+    (m, c) <- get     st <- lift $ expandSyn ast --    lift $ qRunIO $ print (ft, st)     case mLookup st m of-        Just (FunD n _ : _) -> return $ VarE n-        Just (SigD n _ : _) -> return $ VarE n+        Just (FunD n _) -> return $ VarE n         _ -> do             tr <- newNameU "_tr"             let mkRec = do-                    put (n, mInsert st [FunD tr [Clause [] (NormalB $ TupE []) []]] m, c)  -- insert something to break recursion, will be replaced below.+                    put (mInsert st (FunD tr [Clause [] (NormalB $ TupE []) []]) m, c)  -- insert something to break recursion, will be replaced below.                     trBiCase ra f ft st-                trty = st `arrow` (maybe st (flip AppT st) mty)              cs <- if ft == st then do                       b <- contains' ft st                       if b then do                           g <- newNameU "_g"                           gcs <- mkRec-                          let dg = [SigD g trty, FunD g gcs]+                          let dg = FunD g gcs                           -- Insert with a dummy type, just to get the definition in the map for mElems.-                          modify $ \ (n', m', c') -> (n', mInsert (ConT g) dg m', c')+                          modify $ \ (m', c') -> (mInsert (ConT g) dg m', c')                           x <- newNameU "_x"                           return [Clause [VarP x] (NormalB $ rbind f (AppE (VarE g) (VarE x))) []]                        else do@@ -327,8 +396,8 @@                        else do                           x <- newNameU "_x"                           return [Clause [VarP x] (NormalB $ ret $ VarE x) []]-            let d = [SigD tr trty, FunD tr cs]-            modify $ \ (n', m', c') -> (n', mInsert st d m', c')+            let d = FunD tr cs+            modify $ \ (m', c') -> (mInsert st d m', c')             return $ VarE tr  trBiCase :: RetAp -> Exp -> Type -> Type -> U [Clause]@@ -350,7 +419,7 @@ trBiTuple :: RetAp -> Exp -> Type -> Type -> [Type] -> U [Clause] trBiTuple ra f ft st ts = do     vs <- mapM (const $ newNameU "_t") ts-    let tupE = LamE (map VarP vs) $ ListE (map VarE vs)+    let tupE = LamE (map VarP vs) $ TupE (map VarE vs)     c <- trMkArm ra f ft st [] TupP tupE ts     return [c] @@ -366,16 +435,15 @@     mapM genArm cons  trMkArm :: RetAp -> Exp -> Type -> Type -> Subst -> ([Pat] -> Pat) -> Exp -> [Type] -> U Clause-trMkArm ra@(mty, ret, apl, _) f ft st s c ec ts = do+trMkArm ra@(ret, apl, _) f ft st s c ec ts = do     vs <- mapM (const $ newNameU "_x") ts     let sub v t = do             let t' = subst s t             tr <- trBi ra f ft t'-            return $ AppE tr (VarE v {- `SigE` t' -}) {- `SigE` mnd t' -}-        mnd x = maybe x (flip AppT x) mty+            return $ AppE tr (VarE v)         conTy = foldr arrow st (map (subst s) ts)     es <- zipWithM sub vs ts-    let body = foldl apl (ret ec {- `SigE` mnd conTy -}) es+    let body = foldl apl (ret ec) es     return $ Clause [c (map VarP vs)] (NormalB body) []  
examples/Main.hs view
@@ -1,6 +1,5 @@-{-# LANGUAGE TemplateHaskell, ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell, ScopedTypeVariables, FlexibleInstances, MultiParamTypeClasses #-} module Main where---import Control.Monad import Data.Generics.Geniplate  data T a = T { x :: Int, y :: a } deriving (Show)@@ -9,69 +8,44 @@  tree x = Bin (Bin (MT True) x True (MT False)) x False (MT True) -uni :: [(Maybe Int, T Int, [Double])] -> [Int]-uni = $(universeBi 'uni)--uniT :: [(Maybe Int, T Int, [Double])] -> [Int]-uniT = $(universeBiT [ [t|Maybe Int|] ] 'uniT)--uni2 :: [B Bool] -> [Int]-uni2 = $(universeBi 'uni2)--uni3 :: [B Bool] -> [Bool]-uni3 = $(universeBi 'uni3)--uni4 :: B Char -> [B Char]-uni4 = $(universeBi 'uni4)--uni5 :: [Int] -> [[Int]]-uni5 = $(universeBi 'uni5)--trans :: (Int -> Int) -> [(Bool,T String)] -> [(Bool,T String)]-trans = $(transformBi 'trans)--trans1 :: (Bool -> Bool) -> B Char -> B Char-trans1 = $(transformBi 'trans1)--trans2 :: (Bool -> Bool) -> B Bool -> B Bool-trans2 = $(transformBi 'trans2)--trans4 :: (B Char -> B Char) -> B Char -> B Char-trans4 = $(transformBi 'trans4)--trans5 :: (Int -> Maybe Int) -> [Int] -> Maybe [Int]-trans5 = $(transformBiM 'trans5)--trans6 :: (Int -> Maybe Int) -> [(Int, Bool)] -> Maybe [(Int, Bool)]-trans6 = $(transformBiM 'trans6)--trans7 :: (Int -> IO Int) -> B Int -> IO (B Int)-trans7 = $(transformBiM 'trans7)+instanceUniverseBi [t| [(Maybe Int, T Int, [Double])] |] [t| Int |]+instanceUniverseBiT [ [t|Maybe Int|] ] [t| [(Maybe Int, T Int, [Float])] |] [t| Int |]+instanceUniverseBi [t| [B Bool] |] [t| Int |]+instanceUniverseBi [t| [B Bool] |] [t| Bool |]+instanceUniverseBi [t| B Char |] [t| B Char |]+instanceUniverseBi [t| [Int] |] [t| [Int] |] -trans8 :: (Bool -> IO Bool) -> B Bool -> IO (B Bool)-trans8 = $(transformBiM 'trans8)+instanceTransformBi [t| Int |] [t| [(Bool,T String)] |]+instanceTransformBi [t| Bool |] [t| B Char |]+instanceTransformBi [t| Bool |] [t| B Bool |]+instanceTransformBi [t| B Char |] [t| B Char |] -trans9 :: (B Char -> IO (B Char)) -> B Char -> IO (B Char)-trans9 = $(transformBiM 'trans9)+instanceTransformBiM [t| Maybe |] [t| Int |] [t| [Int] |]+instanceTransformBiM [t| Maybe |] [t| Int |] [t| [(Int,Bool)] |]+instanceTransformBiM [t| IO |] [t| Int |] [t| B Int |]+instanceTransformBiM [t| IO |] [t| Bool |] [t| B Bool |]+instanceTransformBiM [t| IO |] [t| B Char |] [t| B Char |]  main :: IO () main = do-    print $ uni  [(Just 12, T 1 2, [1.1]), (Just 345, T 3 4, [2.2]), (Nothing, T 5 6, [3.3])]-    print $ uniT [(Just 12, T 1 2, [1.1]), (Just 345, T 3 4, [2.2]), (Nothing, T 5 6, [3.3])]-    print $ uni2 $ [tree True, tree False]-    print $ uni3 $ [tree True, tree False]-    print $ trans (+1) [(True,T 1 "a"), (False,T 2 "b")]-    print $ trans1 not $ tree 'a'-    print $ trans2 not $ tree True-    print $ uni4 $ tree 'a'-    let f (MT b) = MT (not b)+    print (universeBi [(Just (12::Int), T 1 (2::Int), [1.1::Double]), (Just 345, T 3 4, [2.2]), (Nothing, T 5 6, [3.3])] :: [Int])+    print (universeBi [(Just (12::Int), T 1 (2::Int), [1.1::Float]),  (Just 345, T 3 4, [2.2]), (Nothing, T 5 6, [3.3])] :: [Int])+    print (universeBi [tree True, tree False] :: [Int])+    print (universeBi [tree True, tree False] :: [Bool])+    print (universeBi (tree 'a') :: [B Char])+    print (universeBi [1,2::Int] :: [[Int]])++    print $ transformBi ((+1) :: Int->Int) [(True,T 1 "a"), (False,T 2 "b")]+    print $ transformBi not $ tree 'a'+    print $ transformBi not $ tree True+    let f (MT b) = MT b         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]-    print $ trans6 Just [(1, True)]-    trans7 (\ x -> do print x; return (x+100)) (tree 3) >>= print-    trans8 (\ x -> do print x; return (not x)) (tree True) >>= print-    trans9 (\ x -> do print x; return x) (tree 'a') >>= print+    print $ transformBi (f :: B Char -> B Char) $ tree 'a'++    print $ transformBiM (Just :: Int -> Maybe Int) [1::Int,2,3]+    print $ transformBiM (\ x -> if x==(2::Int) then Nothing else Just x) [1::Int,2,3]+    print $ transformBiM (Just :: Int -> Maybe Int) [(1::Int, True)]+    transformBiM (\ x -> do print (x::Int); return (x+100::Int)) (tree (3::Int)) >>= print+    transformBiM (\ x -> do print (x::Bool); return (not x)) (tree True) >>= print+    transformBiM (\ x -> do print (x::B Char); return x) (tree 'a') >>= print 
geniplate.cabal view
@@ -1,6 +1,6 @@ Name:           geniplate Cabal-Version:  >= 1.2-Version:        0.4.0.1+Version:        0.5.0.0 License:        BSD3 Author:         Lennart Augustsson Maintainer:     Lennart Augustsson