packages feed

TTTAS 0.3.0 → 0.4.0

raw patch · 5 files changed

+489/−490 lines, 5 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

- Language.TTTAS: (&&&&) :: (Arrow2 arr) => arr a b -> arr a b' -> arr a (Pair b b')
- Language.TTTAS: (****) :: (Arrow2 arr) => arr a b -> arr a' b' -> arr (Pair a a') (Pair b b')
- Language.TTTAS: (>>>>) :: (Category2 cat) => cat a b -> cat b c -> cat a c
- Language.TTTAS: Empty :: Env t use ()
- Language.TTTAS: Eq :: Equal a a
- Language.TTTAS: Ext :: Env t use def' -> t a use -> Env t use (def', a)
- Language.TTTAS: List :: [a s] -> List a s
- Language.TTTAS: P :: (a s, b s) -> Pair a b s
- Language.TTTAS: Result :: (m s) -> (b s) -> (FinalEnv t s) -> Result m t b
- Language.TTTAS: Suc :: Ref a env' -> Ref a (env', b)
- Language.TTTAS: T :: (forall x. Ref x e -> Ref x s) -> T e s
- Language.TTTAS: Trafo :: (forall env1. m env1 -> TrafoE m t s env1 a b) -> Trafo m t s a b
- Language.TTTAS: Trafo2 :: (forall env1. m env1 -> TrafoE2 m t env1 a b) -> Trafo2 m t a b
- Language.TTTAS: TrafoE :: (m env2) -> (a -> T env2 s -> Env t s env1 -> (FinalEnv t s -> FinalEnv t s) -> (b, T env1 s, Env t s env2, FinalEnv t s -> FinalEnv t s)) -> TrafoE m t s env1 a b
- Language.TTTAS: TrafoE2 :: (m env2) -> (forall s. a s -> T env2 s -> Env t s env1 -> UpdFinalEnv t s -> (b s, T env1 s, Env t s env2, UpdFinalEnv t s)) -> TrafoE2 m t env1 a b
- Language.TTTAS: Unit :: Unit s
- Language.TTTAS: Upd :: (FinalEnv t s -> FinalEnv t s) -> UpdFinalEnv t s
- Language.TTTAS: Zero :: Ref a (env', a)
- Language.TTTAS: arr2 :: (Arrow2 arr) => (forall s. a s -> b s) -> arr a b
- Language.TTTAS: castSRef :: m e -> Ref a e -> TrafoE m t s e x (Ref a s)
- Language.TTTAS: class (Category2 arr) => Arrow2 arr
- Language.TTTAS: class (Arrow2 arr) => ArrowLoop2 arr
- Language.TTTAS: data Env term use def
- Language.TTTAS: data Equal :: * -> * -> *
- Language.TTTAS: data Ref a env
- Language.TTTAS: data Result m t b
- Language.TTTAS: data Trafo m t s a b
- Language.TTTAS: data Trafo2 m t a b
- Language.TTTAS: data TrafoE m t s env1 a b
- Language.TTTAS: data TrafoE2 m t env1 a b
- Language.TTTAS: data Unit s
- Language.TTTAS: extEnv :: m (e, a) -> TrafoE m t s e (t a s) (Ref a s)
- Language.TTTAS: first2 :: (Arrow2 arr) => arr a b -> arr (Pair a c) (Pair b c)
- Language.TTTAS: instance Arrow (Trafo m t s)
- Language.TTTAS: instance Arrow2 (Trafo2 m t)
- Language.TTTAS: instance ArrowLoop (Trafo m t s)
- Language.TTTAS: instance ArrowLoop2 (Trafo2 m t)
- Language.TTTAS: instance Category (Trafo m t s)
- Language.TTTAS: instance Category2 (Trafo2 m t)
- Language.TTTAS: instance Functor (TrafoE m t s e a)
- Language.TTTAS: lookup :: Ref a env -> env -> a
- Language.TTTAS: lookupEnv :: Ref a env -> Env t s env -> t a s
- Language.TTTAS: loop2 :: (ArrowLoop2 arr) => arr (Pair a c) (Pair b c) -> arr a b
- Language.TTTAS: match :: Ref a env -> Ref b env -> Maybe (Equal a b)
- Language.TTTAS: newSRef :: Trafo Unit t s (t a s) (Ref a s)
- Language.TTTAS: newSRef2 :: Trafo2 Unit t (t a) (Ref a)
- Language.TTTAS: newtype List a s
- Language.TTTAS: newtype Pair a b s
- Language.TTTAS: newtype T e s
- Language.TTTAS: newtype UpdFinalEnv t s
- Language.TTTAS: runTrafo :: (forall s. Trafo m t s a (b s)) -> m () -> a -> Result m t b
- Language.TTTAS: runTrafo2 :: Trafo2 m t a b -> m () -> (forall s. a s) -> Result m t b
- Language.TTTAS: second2 :: (Arrow2 arr) => arr a b -> arr (Pair c a) (Pair c b)
- Language.TTTAS: sequenceA :: [Trafo m t s a b] -> Trafo m t s a [b]
- Language.TTTAS: sequenceA2 :: [Trafo2 m t a b] -> Trafo2 m t a (List b)
- Language.TTTAS: type FinalEnv t usedef = Env t usedef usedef
- Language.TTTAS: unT :: T e s -> forall x. Ref x e -> Ref x s
- Language.TTTAS: update :: (a -> a) -> Ref a env -> env -> env
- Language.TTTAS: updateEnv :: (t a s -> t a s) -> Ref a env -> Env t s env -> Env t s env
- Language.TTTAS: updateFinalEnv :: Trafo m t s (FinalEnv t s -> FinalEnv t s) ()
- Language.TTTAS: updateFinalEnv2 :: Trafo2 m t (UpdFinalEnv t) Unit
- Language.TTTAS: updateSRef :: m e -> Ref a e -> (i -> t a s -> t a s) -> TrafoE m t s e i (Ref a s)
+ Language.AbstractSyntax.TTTAS: (&&&&) :: (Arrow2 arr) => arr a b -> arr a b' -> arr a (Pair b b')
+ Language.AbstractSyntax.TTTAS: (****) :: (Arrow2 arr) => arr a b -> arr a' b' -> arr (Pair a a') (Pair b b')
+ Language.AbstractSyntax.TTTAS: (>>>>) :: (Category2 cat) => cat a b -> cat b c -> cat a c
+ Language.AbstractSyntax.TTTAS: Empty :: Env t use ()
+ Language.AbstractSyntax.TTTAS: Eq :: Equal a a
+ Language.AbstractSyntax.TTTAS: Ext :: Env t use def' -> t a use -> Env t use (def', a)
+ Language.AbstractSyntax.TTTAS: List :: [a s] -> List a s
+ Language.AbstractSyntax.TTTAS: P :: (a s, b s) -> Pair a b s
+ Language.AbstractSyntax.TTTAS: Result :: (m s) -> (b s) -> (FinalEnv t s) -> Result m t b
+ Language.AbstractSyntax.TTTAS: Suc :: Ref a env' -> Ref a (env', b)
+ Language.AbstractSyntax.TTTAS: T :: (forall x. Ref x e -> Ref x s) -> T e s
+ Language.AbstractSyntax.TTTAS: Trafo :: (forall env1. m env1 -> TrafoE m t s env1 a b) -> Trafo m t s a b
+ Language.AbstractSyntax.TTTAS: Trafo2 :: (forall env1. m env1 -> TrafoE2 m t env1 a b) -> Trafo2 m t a b
+ Language.AbstractSyntax.TTTAS: TrafoE :: (m env2) -> (a -> T env2 s -> Env t s env1 -> (FinalEnv t s -> FinalEnv t s) -> (b, T env1 s, Env t s env2, FinalEnv t s -> FinalEnv t s)) -> TrafoE m t s env1 a b
+ Language.AbstractSyntax.TTTAS: TrafoE2 :: (m env2) -> (forall s. a s -> T env2 s -> Env t s env1 -> UpdFinalEnv t s -> (b s, T env1 s, Env t s env2, UpdFinalEnv t s)) -> TrafoE2 m t env1 a b
+ Language.AbstractSyntax.TTTAS: Unit :: Unit s
+ Language.AbstractSyntax.TTTAS: Upd :: (FinalEnv t s -> FinalEnv t s) -> UpdFinalEnv t s
+ Language.AbstractSyntax.TTTAS: Zero :: Ref a (env', a)
+ Language.AbstractSyntax.TTTAS: arr2 :: (Arrow2 arr) => (forall s. a s -> b s) -> arr a b
+ Language.AbstractSyntax.TTTAS: castSRef :: m e -> Ref a e -> TrafoE m t s e x (Ref a s)
+ Language.AbstractSyntax.TTTAS: class (Category2 arr) => Arrow2 arr
+ Language.AbstractSyntax.TTTAS: class (Arrow2 arr) => ArrowLoop2 arr
+ Language.AbstractSyntax.TTTAS: data Env term use def
+ Language.AbstractSyntax.TTTAS: data Equal :: * -> * -> *
+ Language.AbstractSyntax.TTTAS: data Ref a env
+ Language.AbstractSyntax.TTTAS: data Result m t b
+ Language.AbstractSyntax.TTTAS: data Trafo m t s a b
+ Language.AbstractSyntax.TTTAS: data Trafo2 m t a b
+ Language.AbstractSyntax.TTTAS: data TrafoE m t s env1 a b
+ Language.AbstractSyntax.TTTAS: data TrafoE2 m t env1 a b
+ Language.AbstractSyntax.TTTAS: data Unit s
+ Language.AbstractSyntax.TTTAS: extEnv :: m (e, a) -> TrafoE m t s e (t a s) (Ref a s)
+ Language.AbstractSyntax.TTTAS: first2 :: (Arrow2 arr) => arr a b -> arr (Pair a c) (Pair b c)
+ Language.AbstractSyntax.TTTAS: instance Arrow (Trafo m t s)
+ Language.AbstractSyntax.TTTAS: instance Arrow2 (Trafo2 m t)
+ Language.AbstractSyntax.TTTAS: instance ArrowLoop (Trafo m t s)
+ Language.AbstractSyntax.TTTAS: instance ArrowLoop2 (Trafo2 m t)
+ Language.AbstractSyntax.TTTAS: instance Category (Trafo m t s)
+ Language.AbstractSyntax.TTTAS: instance Category2 (Trafo2 m t)
+ Language.AbstractSyntax.TTTAS: instance Functor (TrafoE m t s e a)
+ Language.AbstractSyntax.TTTAS: lookup :: Ref a env -> env -> a
+ Language.AbstractSyntax.TTTAS: lookupEnv :: Ref a env -> Env t s env -> t a s
+ Language.AbstractSyntax.TTTAS: loop2 :: (ArrowLoop2 arr) => arr (Pair a c) (Pair b c) -> arr a b
+ Language.AbstractSyntax.TTTAS: match :: Ref a env -> Ref b env -> Maybe (Equal a b)
+ Language.AbstractSyntax.TTTAS: newSRef :: Trafo Unit t s (t a s) (Ref a s)
+ Language.AbstractSyntax.TTTAS: newSRef2 :: Trafo2 Unit t (t a) (Ref a)
+ Language.AbstractSyntax.TTTAS: newtype List a s
+ Language.AbstractSyntax.TTTAS: newtype Pair a b s
+ Language.AbstractSyntax.TTTAS: newtype T e s
+ Language.AbstractSyntax.TTTAS: newtype UpdFinalEnv t s
+ Language.AbstractSyntax.TTTAS: runTrafo :: (forall s. Trafo m t s a (b s)) -> m () -> a -> Result m t b
+ Language.AbstractSyntax.TTTAS: runTrafo2 :: Trafo2 m t a b -> m () -> (forall s. a s) -> Result m t b
+ Language.AbstractSyntax.TTTAS: second2 :: (Arrow2 arr) => arr a b -> arr (Pair c a) (Pair c b)
+ Language.AbstractSyntax.TTTAS: sequenceA :: [Trafo m t s a b] -> Trafo m t s a [b]
+ Language.AbstractSyntax.TTTAS: sequenceA2 :: [Trafo2 m t a b] -> Trafo2 m t a (List b)
+ Language.AbstractSyntax.TTTAS: type FinalEnv t usedef = Env t usedef usedef
+ Language.AbstractSyntax.TTTAS: unT :: T e s -> forall x. Ref x e -> Ref x s
+ Language.AbstractSyntax.TTTAS: update :: (a -> a) -> Ref a env -> env -> env
+ Language.AbstractSyntax.TTTAS: updateEnv :: (t a s -> t a s) -> Ref a env -> Env t s env -> Env t s env
+ Language.AbstractSyntax.TTTAS: updateFinalEnv :: Trafo m t s (FinalEnv t s -> FinalEnv t s) ()
+ Language.AbstractSyntax.TTTAS: updateFinalEnv2 :: Trafo2 m t (UpdFinalEnv t) Unit
+ Language.AbstractSyntax.TTTAS: updateSRef :: m e -> Ref a e -> (i -> t a s -> t a s) -> TrafoE m t s e i (Ref a s)

Files

TTTAS.cabal view
@@ -1,18 +1,17 @@ cabal-version:      >=1.2.3 build-type:         Simple name:               TTTAS-version:            0.3.0+version:            0.4.0 license:            LGPL license-file:       COPYRIGHT-maintainer:         Arthur Baars <abaars@iti.upv.es>+maintainer:         Marcos Viera <mviera@fing.edu.uy> homepage:           http://www.cs.uu.nl/wiki/bin/view/Center/TTTAS-description: +description:        Library for Typed Transformations of Typed Abstract Syntax synopsis:           Typed Transformations of Typed Abstract Syntax-category: -stability:          Stable+category:           Language  copyright:          Universiteit Utrecht-build-depends:      base >= 2 && < 4.1.0.0, haskell98-exposed-modules:    Language.TTTAS       +build-depends:      base >= 4 && < 5, haskell98+exposed-modules:    Language.AbstractSyntax.TTTAS        extensions:         Arrows, GADTs, CPP hs-source-dirs:     src extra-source-files: README, LICENSE-LGPL, TTTAS.bib
examples/CSE.hs view
@@ -2,7 +2,7 @@  module CSE where -import Language.TTTAS+import Language.AbstractSyntax.TTTAS import Prelude hiding (lookup) import Control.Arrow @@ -185,8 +185,8 @@  trafo :: Decls env -> TrafoCSE env s () (T env s) trafo decls =  proc _ -> -                     mdo  let tt = refTransformer refs-                          refs <- cse_env decls -< tt+                      do  rec  let tt = refTransformer refs+                               refs <- cse_env decls -< tt                           returnA -< tt  cse :: forall env . Decls env -> TDecls env
examples/CSE2.hs view
@@ -1,7 +1,7 @@ {-# OPTIONS -fglasgow-exts  #-} module CSE2 where -  import Language.TTTAS+  import Language.AbstractSyntax.TTTAS     data Expr1 a where
+ src/Language/AbstractSyntax/TTTAS.hs view
@@ -0,0 +1,479 @@+{-# OPTIONS -fglasgow-exts -XArrows #-}
+{-# LANGUAGE CPP #-}
+
+{-| 
+    Library for Typed Transformations of Typed Abstract Syntax.
+
+    The library is documented in the paper: /Typed Transformations of Typed Abstract Syntax/
+
+    Bibtex entry: <http://www.cs.uu.nl/wiki/bin/viewfile/Center/TTTAS?rev=1;filename=TTTAS.bib>
+
+    For more documentation see the TTTAS webpage: 
+    <http://www.cs.uu.nl/wiki/bin/view/Center/TTTAS>.
+-}
+
+module Language.AbstractSyntax.TTTAS (
+               -- * Typed References and Environments
+
+               -- ** Typed References
+               Ref(..), Equal(..), 
+               match, lookup, update,
+
+               -- ** Declarations
+               Env(..), FinalEnv, T(..),
+               lookupEnv, updateEnv,
+
+               -- * Transformation Library
+               
+               -- ** Trafo
+               Trafo(..), TrafoE(..),
+
+               -- ** Create New References
+               Unit(..),
+               newSRef, extEnv, castSRef, updateSRef,
+
+               -- ** Update the Final Environment
+               updateFinalEnv,
+ 
+               -- ** Run a Trafo
+               Result(..), 
+               runTrafo,
+
+               -- ** Other Combinators
+               sequenceA,
+
+               -- * Alternative Transformation Library
+               
+               -- ** Trafo2
+               Trafo2(..), TrafoE2(..),
+
+               -- ** Create New References
+               newSRef2,
+
+               -- ** Update the Final Environment
+               UpdFinalEnv(..), updateFinalEnv2,
+
+               -- ** Run a Trafo2 
+               runTrafo2,
+
+               -- ** Arrow-style Combinators
+               Pair(..), Arrow2(..), ArrowLoop2(..),
+               (>>>>),
+               List(..), sequenceA2
+
+             ) where
+ 
+import Unsafe.Coerce ( unsafeCoerce )
+import qualified Prelude as P
+
+#if __GLASGOW_HASKELL__ >= 609 
+import Control.Category 
+import Prelude hiding (lookup,(.), id) 
+#endif   
+
+import Control.Arrow 
+#if __GLASGOW_HASKELL__ < 609 
+  hiding (pure) 
+import Prelude hiding (lookup)
+#endif
+
+
+-- | The 'Ref' type for represents typed indices which are
+--   labeled with both the type of value to which they
+--   refer and the type of the environment (a nested
+--   Cartesian product, growing to the right) in which 
+--   this value lives.
+ --  The constructor 'Zero' expresses that the first
+ --   element of the environment has to be of type @a@.
+ --  The constructor 'Suc' does not care about the type
+ --   of the first element in the environment, 
+ --   being polymorphic in the type @b@.
+data Ref a env where
+ Zero  ::                      Ref a (env',a)
+ Suc   ::  Ref a      env' ->  Ref a (env',b)
+
+-- | The 'Equal' type encodes type equality. 
+data Equal :: * -> * -> * where 
+ Eq :: Equal a a
+
+-- | The function 'match' compares two references for equality.
+--   If they refer to the same element in the environment
+--   the value @Just Eq@ is returned, expressing the fact that
+--   the types of the referred values are the same too.
+match :: Ref a env -> Ref b env -> Maybe (Equal a b)
+match  Zero     Zero        =  Just Eq
+match  (Suc x)  (Suc y)     =  match x y
+match  _        _           =  Nothing
+
+-- | The function 'lookup' returns the element indexed in the
+--   environment parameter by the 'Ref' parameter. The types
+--   guarantee that the lookup succeeds.
+lookup :: Ref a env -> env -> a
+lookup  Zero     (_,a)  =  a
+lookup  (Suc r)  (e,_)  =  lookup r e
+
+-- | The function 'update' takes an additional function as
+--   argument, which is used to update the value the 
+--   reference addresses.
+update :: (a -> a) -> Ref a env -> env -> env  
+update f  Zero     (e,a)   =  (e,f a)
+update f  (Suc r)  (e,x)   =  (update f r e,x)
+
+
+-- | The type @Env term use def@ represents a sequence of
+--   instantiations of type @forall a. term a use@, where
+--   all the instances of @a@ are stored in the type parameter
+--   @def@. The type @use@ is a sequence containing the 
+--   types to which may be referred from within terms of type
+--   @term a use@. 
+data Env term use def where
+  Empty  ::  Env t use  ()
+  Ext    ::  Env t use def' ->  t a use  
+         ->  Env t use  (def',a)
+
+
+lookupEnv  :: Ref a env -> Env t s env -> t a s
+lookupEnv  Zero     (Ext _ t)   =  t
+lookupEnv  (Suc r)  (Ext ts _)  =  lookupEnv r ts
+lookupEnv  _        _           =  error "Error: The impossible happened!"
+
+updateEnv  ::  (t a s -> t a s) -> Ref a env 
+           ->  Env t s env ->  Env t s env
+updateEnv  f  Zero     (Ext ts t)  
+              =        Ext ts (f t) 
+updateEnv  f  (Suc r)  (Ext ts t)  
+              =        Ext (updateEnv f r ts)  t
+updateEnv  _  _        _ 
+              =  error "Error: The impossible happened!"
+
+
+-- | When the types @def@ and @use@ of an 'Env' coincide,
+--   we can be sure that the references in the terms do not
+--   point to values outside the environment but point
+--   to terms representing the right type. This kind of
+--   environment is the /final environment/ of a transformation.
+type FinalEnv t usedef = Env t usedef usedef
+ 
+-- | The type 'T' encodes a 'Ref'-transformer. It is usually used
+--   to transform references from an actual environment to 
+--   the final one.
+newtype T e s  = T {unT :: forall x . Ref x e -> Ref x s}
+
+-- | The type 'Trafo' is the type of the transformation steps on a heterogeneous collection.
+--   The argument @m@ stands for the type of the meta-data.  
+--   A |Trafo| takes the meta-data on the current environment |env1| as input and 
+--   yields  meta-data for the (possibly extended) environment |env2|.
+--   The type @t@ is the type of the terms stored in the environment.
+--   The type variable @s@ represents the type of the final result, which we do expose. 
+--   Its role is similar to the @s@ in the type @ST s a@.
+--   The arguments @a@ and @b@ are the Arrow's input and output, respectively.
+data  Trafo  m t s a b =  
+  Trafo (forall env1 . m env1 -> TrafoE m t s env1 a b)
+
+-- | The type 'TrafoE' is used to introduce an existential quantifier into
+--   the definition of 'Trafo'.  
+--   It can be seen that a 'Trafo' is a function taking as arguments: the input (@a@),
+--   a 'Ref'-transformer (@T env2 s@) from the environment constructed in this step 
+--   to the final environment, the environment (@Env t s env1@) where the current 
+--   transformation starts and a function (@FinalEnv t s -> FinalEnv t s@) to update 
+--   (modify) the final environment. The function returns: the output (@b@), 
+--   a 'Ref'-transformer (@T env1 s@) from the initial environment of this step to the final 
+--   environment, the environment (@Env t s env2@) constructed in this step and a function 
+--   (@FinalEnv t s -> FinalEnv t s@) to update (modify) the final environment.
+--   NOTE: The function (@FinalEnv t s -> FinalEnv t s@) was introduced in version 0.3. 
+--   It's carried throw the transformation steps and can be modified (composed to another function)
+--   using the function 'updateFinalEnv'.
+data  TrafoE m t s env1 a b = 
+ forall env2 . TrafoE   (  m env2)
+                        (       a  ->  T env2 s ->  Env t s env1 -> (FinalEnv t s -> FinalEnv t s)
+                          -> (  b,     T env1 s,    Env t s env2, (FinalEnv t s -> FinalEnv t s))
+                        )
+
+data Unit s         = Unit
+
+-- |  The Trafo 'newSRef' takes a typed term as input, adds it to the environment 
+--    and yields a reference pointing to this value.
+--    No meta-information on the environment is recorded by 'newSRef';
+--    therefore we use the type 'Unit' for the meta-data.  
+newSRef :: Trafo Unit t s (t a s) (Ref a s)
+newSRef 
+ =  Trafo  (\ _->  extEnv Unit)
+
+
+-- | The function 'updateFinalEnv' returns a 'Trafo' that introduces a function
+--   (@FinalEnv t s -> FinalEnv t s@) to update the final environment.
+updateFinalEnv ::  Trafo m t s (FinalEnv t s -> FinalEnv t s) ()
+updateFinalEnv = Trafo $ \m -> (TrafoE m (\f' t e f -> ((), t, e, f' . f)))
+
+
+-- | The function 'extEnv' returns a 'TrafoE' that extends the current environment.
+extEnv :: m (e,a) -> TrafoE m t s e (t a s) (Ref a s)
+extEnv m = TrafoE m $ \ta  (T tr) env  f ->  (tr Zero,  T (tr P.. Suc),  Ext env ta, f )
+
+-- | The function 'castSRef'  returns a 'TrafoE' that casts the reference 
+--   passed as parameter (in the constructed environment) to one in the final environment.
+castSRef :: m e -> Ref a e -> TrafoE m t s e x (Ref a s)
+castSRef m r = TrafoE m $ (\   _ (T t) decls f ->  (t r, T t, decls, f))
+
+-- | The function 'updateSRef' returns a 'TrafoE' that updates the value pointed
+--   by the reference passed as parameter into the current environment.
+updateSRef :: m e -> Ref a e -> (i -> t a s -> t a s) -> TrafoE m t s e i (Ref a s)
+updateSRef m r f = TrafoE m $ \i (T t) decls fs -> (t r, T t, updateEnv (f i) r decls, fs)
+
+
+instance Functor (TrafoE m t s e a) where
+ fmap f (TrafoE m step) = TrafoE m $ \i t e fs -> case step i t e fs of
+                                                  (i',t',e',fs') -> (f i',t',e',fs')
+
+-- | The type 'Result' is the type of the result of \"running\" a 'Trafo'. 
+--   Because @s@ could be anything we have to hide it using existential quantification.
+data Result  m t b   
+   =  forall s . Result  (m s) (b s) (FinalEnv t s)
+
+-- | The function 'runTrafo' takes as arguments the 'Trafo' we want to run, meta-information 
+--   for the empty environment, and an input value. 
+--   The result of 'runTrafo' (type 'Result') is the final environment (@Env t s s@) together 
+--   with the resulting meta-data (@m s@), and the output value (@b s@). 
+--   The rank-2 type for 'runTrafo' ensures that transformation steps cannot make 
+--   any assumptions about the type of final environment (@s@).
+runTrafo   ::  (forall s . Trafo m t s a (b s)) ->  m () -> a 
+           ->  Result m t b
+runTrafo trafo m a = case trafo of
+  Trafo trf -> case trf m of
+                   TrafoE m2 f -> 
+                     case  f a (T unsafeCoerce) Empty P.id of  -- the function could also be passed as argument
+                       (rb, _, env2, fenvs) -> 
+                         Result  (unsafeCoerce m2)  
+                                 rb 
+                                 (fenvs $ unsafeCoerce env2) 
+
+#if __GLASGOW_HASKELL__ >= 609
+
+instance Category (Trafo m t s) where
+ -- |(.) :: Trafo m t s b c  ->  Trafo m t s a b ->  Trafo m t s a c|
+ Trafo t2 . Trafo t1 = 
+  Trafo 
+  (\m1 -> case t1 m1 of
+                                      TrafoE m2 f1 -> case t2 m2 of
+                                       TrafoE m3 f2 ->
+                                        TrafoE 
+                                        m3 
+                                        (\a  tt env1 fs ->
+                                             let  (b,tt1, env2, fs')   = f1 a tt2 env1 fs
+                                                  (c,tt2, env3, fs'')  = f2 b tt env2 fs'
+                                             in   (c,tt1, env3, fs'')                                                                    
+                                        )
+  )
+
+ -- |id :: Trafo m t s a a|
+ id =  Trafo  (\m -> TrafoE m (\a t e f -> (a, t, e, f)) )
+
+#endif
+
+
+instance Arrow (Trafo m t s) where
+
+ -- |arr :: (a  -> b) -> Trafo m t s a b|
+ arr f =  Trafo  (\m -> TrafoE m (\a t e fs -> (f a, t, e, fs)) )
+
+#if __GLASGOW_HASKELL__ < 609 
+
+ Trafo t1 >>> Trafo t2 = 
+  Trafo 
+  (\m1 -> case t1 m1 of
+                                      TrafoE m2 f1 -> case t2 m2 of
+                                       TrafoE m3 f2 ->
+                                        TrafoE 
+                                        m3 
+                                        (\a  tt env1 fs ->
+                                             let  (b,tt1, env2, fs')   = f1 a tt2 env1 fs
+                                                  (c,tt2, env3, fs'')  = f2 b tt env2 fs'
+                                             in   (c,tt1, env3, fs'')                                                                    
+                                        )
+  )
+
+#endif 
+
+ -- |first :: Trafo m t s a b -> Trafo m t s (a, c) (b, c)|
+ first (Trafo tr) 
+  = Trafo (\m1 -> case tr m1 of
+        TrafoE m2 f -> 
+           TrafoE  
+           m2 
+           (\  ~(a,c) tt env1 fs -> 
+               let (b,tt1,env2, fs') = f a tt env1 fs
+               in  ((b,c),tt1, env2, fs'))) 
+
+
+instance ArrowLoop (Trafo m t s) where
+ -- |loop :: Trafo m t s (a, x) (b, x) -> Trafo m t s a b|
+ loop (Trafo st) =
+   Trafo 
+   (\m -> case st m of
+           TrafoE m1 f1 ->
+            TrafoE  m1
+            (\a t e f -> 
+              let ((b, x),t1,e1,f') = f1 (a, x) t e f                                                                            
+              in (b,t1,e1,f')
+            ))
+
+-- | The combinator 'sequenceA' sequentially composes a list
+--   of 'Trafo's into a 'Trafo' that yields a list of outputs.
+--   Its use is analogous to the combinator 'sequence' combinator
+--   for 'Monad's.
+sequenceA :: [Trafo m t s a b] -> Trafo m t s a [b]
+sequenceA [] = arr (const [])
+sequenceA (x:xs) 
+     = proc a ->
+        do b  <- x -< a
+           bs <- sequenceA xs -< a
+           returnA -< (b:bs)  
+
+
+
+
+
+-- | Alternative version of 'Trafo' where the universal quantification 
+--   over |s| is moved inside the quantification over |env2|.
+--   Note that the type variables |a| and |b| are now labelled with |s|, 
+--   and hence have kind |(* -> *)|.
+data  Trafo2  m t a b =  
+  Trafo2 (forall env1 . m env1 -> TrafoE2 m t env1 a b)
+data  TrafoE2 m t env1 a b = 
+  forall env2 .  TrafoE2
+                 (m env2)
+                 (forall s .  a s -> T env2 s -> Env t s env1 -> UpdFinalEnv t s
+                              -> (b s, T env1 s, Env t s env2, UpdFinalEnv t s)
+                 )
+
+newtype UpdFinalEnv t s = Upd (FinalEnv t s -> FinalEnv t s)
+
+-- | The function 'runTrafo2' takes as arguments the 'Trafo2' we want to run, meta-information 
+--   for the empty environment, and an input value. 
+--   The result of 'runTrafo2' (type 'Result') is the final environment (@Env t s s@) together 
+--   with the resulting meta-data (@m s@), and the output value (@b s@). 
+--   The rank-2 type for 'runTrafo2' ensures that transformation steps cannot make 
+--   any assumptions about the type of final environment (@s@).
+--   It is an alternative version of 'runTrafo' which does not use
+--   'unsafeCoerce'.
+runTrafo2  ::  Trafo2 m t a b -> m () -> (forall s . a s) 
+           ->  Result m t b
+runTrafo2 trafo m a = 
+ case trafo of
+  Trafo2 trf -> case trf m of
+                   TrafoE2 m2 f -> 
+                      let  (rb, _, env2, Upd upds) =  f a (T P.id) Empty (Upd P.id)
+                      in   Result m2  rb (upds env2)
+
+
+-- |  The Trafo2 'newSRef2' takes a typed term as input, adds it to the environment 
+--    and yields a reference pointing to this value.
+--    No meta-information on the environment is recorded by 'newSRef2';
+--    therefore we use the type 'Unit' for the meta-data.  
+newSRef2 :: Trafo2 Unit t (t a) (Ref a)
+newSRef2 
+    =  Trafo2  
+       (\Unit ->  TrafoE2  
+                  Unit
+                  (\ta (T tr) env upds ->
+                      ( tr Zero
+                      , T (tr P.. Suc)
+                      , Ext env ta
+                      , upds
+       )          )   )
+
+
+-- | The function 'updateFinalEnv2' returns a 'Trafo2' that introduces a function
+--   (@(UpdFinalEnv t)@) to update the final environment.
+updateFinalEnv2 ::  Trafo2 m t (UpdFinalEnv t) Unit
+updateFinalEnv2 = Trafo2 $ \m -> (TrafoE2 m (\(Upd u') t e (Upd u) -> (Unit, t, e, (Upd $ u' P.. u))))
+
+
+newtype Pair a b s = P (a s, b s)
+
+class Category2 cat where
+  id2     :: cat a a
+  (.:.)   :: cat b c -> cat a b -> cat a c
+
+class Category2 arr => Arrow2 arr where
+  arr2    :: (forall s . a s -> b s) -> arr a b
+  first2  :: arr a b -> arr (Pair a c) (Pair b c)
+  second2 :: arr a b -> arr (Pair c a) (Pair c b)
+  (****)  :: arr a b -> arr a' b'
+          -> arr (Pair a a') (Pair b b')
+  (&&&&)  :: arr a b -> arr a b' -> arr a (Pair b b')
+
+class Arrow2 arr => ArrowLoop2 arr where
+  loop2   :: arr (Pair a c) (Pair b c) -> arr a b
+
+
+instance Category2 (Trafo2 m t) where
+  id2   =  Trafo2  (\m -> TrafoE2 m (\a t e u -> (a, t, e, u)))
+
+  (.:.) (Trafo2 sb) (Trafo2 sa) = 
+    Trafo2 
+    (\m1 ->
+       case sa m1 of 
+        TrafoE2 m2 f1 -> case sb m2 of 
+         TrafoE2 m3 f2 -> 
+           TrafoE2  
+           m3 
+           (\a t3s e1 u1 -> let  (b, t1s, e2, u2) = f1 a t2s e1 u1
+                                 (c, t2s, e3, u3) = f2 b t3s e2 u2
+                            in   (c, t1s, e3, u3)
+           ))
+
+
+(>>>>) :: Category2 cat => cat a b -> cat b c -> cat a c
+f >>>> g = g .:. f
+
+ 
+instance Arrow2 (Trafo2 m t) where
+  arr2 f 
+    =  Trafo2  (\m -> TrafoE2 m (\a t e u -> (f a, t, e, u)) )
+
+  
+  first2 (Trafo2 s) 
+    =  Trafo2
+       (\m1 -> case s m1 of
+          TrafoE2 m2 f -> 
+             TrafoE2  m2
+                    (\(P (a, c)) t2s e1 u1 -> 
+                                      let (b,t12,e2,u2) = f a t2s e1 u1 
+                                      in  (P (b, c),t12,e2,u2)
+                    )              
+       ) 
+
+  second2 f = arr2 swap >>>> first2 f >>>> arr2 swap
+              where   swap ~(P (x, y)) = P (y, x)
+             
+  f **** g =  first2 f >>>> second2 g  
+ 
+  f &&&& g = arr2 (\b -> P (b, b)) >>>> (f **** g)      
+
+
+instance ArrowLoop2 (Trafo2 m t) where
+  loop2 (Trafo2 st) =
+    Trafo2 
+    (\m -> case st m of
+            TrafoE2 m1 f1 ->
+             TrafoE2  m1
+             (\a t e u -> 
+               let (P (b, x),t1,e1,u1) = f1 (P (a, x)) t e u                                                                            
+               in (b,t1,e1,u1)
+             ) 
+    )
+
+
+newtype List a s = List [a s]
+
+-- | The combinator 'sequenceA2' sequentially composes a list
+--   of 'Trafo2's into a 'Trafo2' that yields a 'List' of outputs.
+--   Its use is analogous to the combinator 'sequence' combinator
+--   for 'Monad's.
+sequenceA2 :: [Trafo2 m t a b] -> Trafo2 m t a (List b)
+sequenceA2 [] = arr2 (const (List []))
+sequenceA2 (x:xs) 
+       =  (x &&&& sequenceA2 xs) >>>> 
+          arr2 (\(P (a,List as)) -> List (a:as))
+
− src/Language/TTTAS.hs
@@ -1,479 +0,0 @@-{-# OPTIONS -fglasgow-exts -XArrows #-}
-{-# LANGUAGE CPP #-}
-
-{-| 
-    Library for Typed Transformations of Typed Abstract Syntax.
-
-    The library is documented in the paper: /Typed Transformations of Typed Abstract Syntax/
-
-    Bibtex entry: <http://www.cs.uu.nl/wiki/bin/viewfile/Center/TTTAS?rev=1;filename=TTTAS.bib>
-
-    For more documentation see the TTTAS webpage: 
-    <http://www.cs.uu.nl/wiki/bin/view/Center/TTTAS>.
--}
-
-module Language.TTTAS (
-               -- * Typed References and Environments
-
-               -- ** Typed References
-               Ref(..), Equal(..), 
-               match, lookup, update,
-
-               -- ** Declarations
-               Env(..), FinalEnv, T(..),
-               lookupEnv, updateEnv,
-
-               -- * Transformation Library
-               
-               -- ** Trafo
-               Trafo(..), TrafoE(..),
-
-               -- ** Create New References
-               Unit(..),
-               newSRef, extEnv, castSRef, updateSRef,
-
-               -- ** Update the Final Environment
-               updateFinalEnv,
- 
-               -- ** Run a Trafo
-               Result(..), 
-               runTrafo,
-
-               -- ** Other Combinators
-               sequenceA,
-
-               -- * Alternative Transformation Library
-               
-               -- ** Trafo2
-               Trafo2(..), TrafoE2(..),
-
-               -- ** Create New References
-               newSRef2,
-
-               -- ** Update the Final Environment
-               UpdFinalEnv(..), updateFinalEnv2,
-
-               -- ** Run a Trafo2 
-               runTrafo2,
-
-               -- ** Arrow-style Combinators
-               Pair(..), Arrow2(..), ArrowLoop2(..),
-               (>>>>),
-               List(..), sequenceA2
-
-             ) where
- 
-import Unsafe.Coerce ( unsafeCoerce )
-import qualified Prelude as P
-
-#if __GLASGOW_HASKELL__ >= 609 
-import Control.Category 
-import Prelude hiding (lookup,(.), id) 
-#endif   
-
-import Control.Arrow 
-#if __GLASGOW_HASKELL__ < 609 
-  hiding (pure) 
-import Prelude hiding (lookup)
-#endif
-
-
--- | The 'Ref' type for represents typed indices which are
---   labeled with both the type of value to which they
---   refer and the type of the environment (a nested
---   Cartesian product, growing to the right) in which 
---   this value lives.
- --  The constructor 'Zero' expresses that the first
- --   element of the environment has to be of type @a@.
- --  The constructor 'Suc' does not care about the type
- --   of the first element in the environment, 
- --   being polymorphic in the type @b@.
-data Ref a env where
- Zero  ::                      Ref a (env',a)
- Suc   ::  Ref a      env' ->  Ref a (env',b)
-
--- | The 'Equal' type encodes type equality. 
-data Equal :: * -> * -> * where 
- Eq :: Equal a a
-
--- | The function 'match' compares two references for equality.
---   If they refer to the same element in the environment
---   the value @Just Eq@ is returned, expressing the fact that
---   the types of the referred values are the same too.
-match :: Ref a env -> Ref b env -> Maybe (Equal a b)
-match  Zero     Zero        =  Just Eq
-match  (Suc x)  (Suc y)     =  match x y
-match  _        _           =  Nothing
-
--- | The function 'lookup' returns the element indexed in the
---   environment parameter by the 'Ref' parameter. The types
---   guarantee that the lookup succeeds.
-lookup :: Ref a env -> env -> a
-lookup  Zero     (_,a)  =  a
-lookup  (Suc r)  (e,_)  =  lookup r e
-
--- | The function 'update' takes an additional function as
---   argument, which is used to update the value the 
---   reference addresses.
-update :: (a -> a) -> Ref a env -> env -> env  
-update f  Zero     (e,a)   =  (e,f a)
-update f  (Suc r)  (e,x)   =  (update f r e,x)
-
-
--- | The type @Env term use def@ represents a sequence of
---   instantiations of type @forall a. term a use@, where
---   all the instances of @a@ are stored in the type parameter
---   @def@. The type @use@ is a sequence containing the 
---   types to which may be referred from within terms of type
---   @term a use@. 
-data Env term use def where
-  Empty  ::  Env t use  ()
-  Ext    ::  Env t use def' ->  t a use  
-         ->  Env t use  (def',a)
-
-
-lookupEnv  :: Ref a env -> Env t s env -> t a s
-lookupEnv  Zero     (Ext _ t)   =  t
-lookupEnv  (Suc r)  (Ext ts _)  =  lookupEnv r ts
-lookupEnv  _        _           =  error "Error: The impossible happened!"
-
-updateEnv  ::  (t a s -> t a s) -> Ref a env 
-           ->  Env t s env ->  Env t s env
-updateEnv  f  Zero     (Ext ts t)  
-              =        Ext ts (f t) 
-updateEnv  f  (Suc r)  (Ext ts t)  
-              =        Ext (updateEnv f r ts)  t
-updateEnv  _  _        _ 
-              =  error "Error: The impossible happened!"
-
-
--- | When the types @def@ and @use@ of an 'Env' coincide,
---   we can be sure that the references in the terms do not
---   point to values outside the environment but point
---   to terms representing the right type. This kind of
---   environment is the /final environment/ of a transformation.
-type FinalEnv t usedef = Env t usedef usedef
- 
--- | The type 'T' encodes a 'Ref'-transformer. It is usually used
---   to transform references from an actual environment to 
---   the final one.
-newtype T e s  = T {unT :: forall x . Ref x e -> Ref x s}
-
--- | The type 'Trafo' is the type of the transformation steps on a heterogeneous collection.
---   The argument @m@ stands for the type of the meta-data.  
---   A |Trafo| takes the meta-data on the current environment |env1| as input and 
---   yields  meta-data for the (possibly extended) environment |env2|.
---   The type @t@ is the type of the terms stored in the environment.
---   The type variable @s@ represents the type of the final result, which we do expose. 
---   Its role is similar to the @s@ in the type @ST s a@.
---   The arguments @a@ and @b@ are the Arrow's input and output, respectively.
-data  Trafo  m t s a b =  
-  Trafo (forall env1 . m env1 -> TrafoE m t s env1 a b)
-
--- | The type 'TrafoE' is used to introduce an existential quantifier into
---   the definition of 'Trafo'.  
---   It can be seen that a 'Trafo' is a function taking as arguments: the input (@a@),
---   a 'Ref'-transformer (@T env2 s@) from the environment constructed in this step 
---   to the final environment, the environment (@Env t s env1@) where the current 
---   transformation starts and a function (@FinalEnv t s -> FinalEnv t s@) to update 
---   (modify) the final environment. The function returns: the output (@b@), 
---   a 'Ref'-transformer (@T env1 s@) from the initial environment of this step to the final 
---   environment, the environment (@Env t s env2@) constructed in this step and a function 
---   (@FinalEnv t s -> FinalEnv t s@) to update (modify) the final environment.
---   NOTE: The function (@FinalEnv t s -> FinalEnv t s@) was introduced in version 0.3. 
---   It's carried throw the transformation steps and can be modified (composed to another function)
---   using the function 'updateFinalEnv'.
-data  TrafoE m t s env1 a b = 
- forall env2 . TrafoE   (  m env2)
-                        (       a  ->  T env2 s ->  Env t s env1 -> (FinalEnv t s -> FinalEnv t s)
-                          -> (  b,     T env1 s,    Env t s env2, (FinalEnv t s -> FinalEnv t s))
-                        )
-
-data Unit s         = Unit
-
--- |  The Trafo 'newSRef' takes a typed term as input, adds it to the environment 
---    and yields a reference pointing to this value.
---    No meta-information on the environment is recorded by 'newSRef';
---    therefore we use the type 'Unit' for the meta-data.  
-newSRef :: Trafo Unit t s (t a s) (Ref a s)
-newSRef 
- =  Trafo  (\ _->  extEnv Unit)
-
-
--- | The function 'updateFinalEnv' returns a 'Trafo' that introduces a function
---   (@FinalEnv t s -> FinalEnv t s@) to update the final environment.
-updateFinalEnv ::  Trafo m t s (FinalEnv t s -> FinalEnv t s) ()
-updateFinalEnv = Trafo $ \m -> (TrafoE m (\f' t e f -> ((), t, e, f' . f)))
-
-
--- | The function 'extEnv' returns a 'TrafoE' that extends the current environment.
-extEnv :: m (e,a) -> TrafoE m t s e (t a s) (Ref a s)
-extEnv m = TrafoE m $ \ta  (T tr) env  f ->  (tr Zero,  T (tr P.. Suc),  Ext env ta, f )
-
--- | The function 'castSRef'  returns a 'TrafoE' that casts the reference 
---   passed as parameter (in the constructed environment) to one in the final environment.
-castSRef :: m e -> Ref a e -> TrafoE m t s e x (Ref a s)
-castSRef m r = TrafoE m $ (\   _ (T t) decls f ->  (t r, T t, decls, f))
-
--- | The function 'updateSRef' returns a 'TrafoE' that updates the value pointed
---   by the reference passed as parameter into the current environment.
-updateSRef :: m e -> Ref a e -> (i -> t a s -> t a s) -> TrafoE m t s e i (Ref a s)
-updateSRef m r f = TrafoE m $ \i (T t) decls fs -> (t r, T t, updateEnv (f i) r decls, fs)
-
-
-instance Functor (TrafoE m t s e a) where
- fmap f (TrafoE m step) = TrafoE m $ \i t e fs -> case step i t e fs of
-                                                  (i',t',e',fs') -> (f i',t',e',fs')
-
--- | The type 'Result' is the type of the result of \"running\" a 'Trafo'. 
---   Because @s@ could be anything we have to hide it using existential quantification.
-data Result  m t b   
-   =  forall s . Result  (m s) (b s) (FinalEnv t s)
-
--- | The function 'runTrafo' takes as arguments the 'Trafo' we want to run, meta-information 
---   for the empty environment, and an input value. 
---   The result of 'runTrafo' (type 'Result') is the final environment (@Env t s s@) together 
---   with the resulting meta-data (@m s@), and the output value (@b s@). 
---   The rank-2 type for 'runTrafo' ensures that transformation steps cannot make 
---   any assumptions about the type of final environment (@s@).
-runTrafo   ::  (forall s . Trafo m t s a (b s)) ->  m () -> a 
-           ->  Result m t b
-runTrafo trafo m a = case trafo of
-  Trafo trf -> case trf m of
-                   TrafoE m2 f -> 
-                     case  f a (T unsafeCoerce) Empty P.id of  -- the function could also be passed as argument
-                       (rb, _, env2, fenvs) -> 
-                         Result  (unsafeCoerce m2)  
-                                 rb 
-                                 (fenvs $ unsafeCoerce env2) 
-
-#if __GLASGOW_HASKELL__ >= 609
-
-instance Category (Trafo m t s) where
- -- |(.) :: Trafo m t s b c  ->  Trafo m t s a b ->  Trafo m t s a c|
- Trafo t2 . Trafo t1 = 
-  Trafo 
-  (\m1 -> case t1 m1 of
-                                      TrafoE m2 f1 -> case t2 m2 of
-                                       TrafoE m3 f2 ->
-                                        TrafoE 
-                                        m3 
-                                        (\a  tt env1 fs ->
-                                             let  (b,tt1, env2, fs')   = f1 a tt2 env1 fs
-                                                  (c,tt2, env3, fs'')  = f2 b tt env2 fs'
-                                             in   (c,tt1, env3, fs'')                                                                    
-                                        )
-  )
-
- -- |id :: Trafo m t s a a|
- id =  Trafo  (\m -> TrafoE m (\a t e f -> (a, t, e, f)) )
-
-#endif
-
-
-instance Arrow (Trafo m t s) where
-
- -- |arr :: (a  -> b) -> Trafo m t s a b|
- arr f =  Trafo  (\m -> TrafoE m (\a t e fs -> (f a, t, e, fs)) )
-
-#if __GLASGOW_HASKELL__ < 609 
-
- Trafo t1 >>> Trafo t2 = 
-  Trafo 
-  (\m1 -> case t1 m1 of
-                                      TrafoE m2 f1 -> case t2 m2 of
-                                       TrafoE m3 f2 ->
-                                        TrafoE 
-                                        m3 
-                                        (\a  tt env1 fs ->
-                                             let  (b,tt1, env2, fs')   = f1 a tt2 env1 fs
-                                                  (c,tt2, env3, fs'')  = f2 b tt env2 fs'
-                                             in   (c,tt1, env3, fs'')                                                                    
-                                        )
-  )
-
-#endif 
-
- -- |first :: Trafo m t s a b -> Trafo m t s (a, c) (b, c)|
- first (Trafo tr) 
-  = Trafo (\m1 -> case tr m1 of
-        TrafoE m2 f -> 
-           TrafoE  
-           m2 
-           (\  ~(a,c) tt env1 fs -> 
-               let (b,tt1,env2, fs') = f a tt env1 fs
-               in  ((b,c),tt1, env2, fs'))) 
-
-
-instance ArrowLoop (Trafo m t s) where
- -- |loop :: Trafo m t s (a, x) (b, x) -> Trafo m t s a b|
- loop (Trafo st) =
-   Trafo 
-   (\m -> case st m of
-           TrafoE m1 f1 ->
-            TrafoE  m1
-            (\a t e f -> 
-              let ((b, x),t1,e1,f') = f1 (a, x) t e f                                                                            
-              in (b,t1,e1,f')
-            ))
-
--- | The combinator 'sequenceA' sequentially composes a list
---   of 'Trafo's into a 'Trafo' that yields a list of outputs.
---   Its use is analogous to the combinator 'sequence' combinator
---   for 'Monad's.
-sequenceA :: [Trafo m t s a b] -> Trafo m t s a [b]
-sequenceA [] = arr (const [])
-sequenceA (x:xs) 
-     = proc a ->
-        do b  <- x -< a
-           bs <- sequenceA xs -< a
-           returnA -< (b:bs)  
-
-
-
-
-
--- | Alternative version of 'Trafo' where the universal quantification 
---   over |s| is moved inside the quantification over |env2|.
---   Note that the type variables |a| and |b| are now labelled with |s|, 
---   and hence have kind |(* -> *)|.
-data  Trafo2  m t a b =  
-  Trafo2 (forall env1 . m env1 -> TrafoE2 m t env1 a b)
-data  TrafoE2 m t env1 a b = 
-  forall env2 .  TrafoE2
-                 (m env2)
-                 (forall s .  a s -> T env2 s -> Env t s env1 -> UpdFinalEnv t s
-                              -> (b s, T env1 s, Env t s env2, UpdFinalEnv t s)
-                 )
-
-newtype UpdFinalEnv t s = Upd (FinalEnv t s -> FinalEnv t s)
-
--- | The function 'runTrafo2' takes as arguments the 'Trafo2' we want to run, meta-information 
---   for the empty environment, and an input value. 
---   The result of 'runTrafo2' (type 'Result') is the final environment (@Env t s s@) together 
---   with the resulting meta-data (@m s@), and the output value (@b s@). 
---   The rank-2 type for 'runTrafo2' ensures that transformation steps cannot make 
---   any assumptions about the type of final environment (@s@).
---   It is an alternative version of 'runTrafo' which does not use
---   'unsafeCoerce'.
-runTrafo2  ::  Trafo2 m t a b -> m () -> (forall s . a s) 
-           ->  Result m t b
-runTrafo2 trafo m a = 
- case trafo of
-  Trafo2 trf -> case trf m of
-                   TrafoE2 m2 f -> 
-                      let  (rb, _, env2, Upd upds) =  f a (T P.id) Empty (Upd P.id)
-                      in   Result m2  rb (upds env2)
-
-
--- |  The Trafo2 'newSRef2' takes a typed term as input, adds it to the environment 
---    and yields a reference pointing to this value.
---    No meta-information on the environment is recorded by 'newSRef2';
---    therefore we use the type 'Unit' for the meta-data.  
-newSRef2 :: Trafo2 Unit t (t a) (Ref a)
-newSRef2 
-    =  Trafo2  
-       (\Unit ->  TrafoE2  
-                  Unit
-                  (\ta (T tr) env upds ->
-                      ( tr Zero
-                      , T (tr P.. Suc)
-                      , Ext env ta
-                      , upds
-       )          )   )
-
-
--- | The function 'updateFinalEnv2' returns a 'Trafo2' that introduces a function
---   (@(UpdFinalEnv t)@) to update the final environment.
-updateFinalEnv2 ::  Trafo2 m t (UpdFinalEnv t) Unit
-updateFinalEnv2 = Trafo2 $ \m -> (TrafoE2 m (\(Upd u') t e (Upd u) -> (Unit, t, e, (Upd $ u' P.. u))))
-
-
-newtype Pair a b s = P (a s, b s)
-
-class Category2 cat where
-  id2     :: cat a a
-  (.:.)   :: cat b c -> cat a b -> cat a c
-
-class Category2 arr => Arrow2 arr where
-  arr2    :: (forall s . a s -> b s) -> arr a b
-  first2  :: arr a b -> arr (Pair a c) (Pair b c)
-  second2 :: arr a b -> arr (Pair c a) (Pair c b)
-  (****)  :: arr a b -> arr a' b'
-          -> arr (Pair a a') (Pair b b')
-  (&&&&)  :: arr a b -> arr a b' -> arr a (Pair b b')
-
-class Arrow2 arr => ArrowLoop2 arr where
-  loop2   :: arr (Pair a c) (Pair b c) -> arr a b
-
-
-instance Category2 (Trafo2 m t) where
-  id2   =  Trafo2  (\m -> TrafoE2 m (\a t e u -> (a, t, e, u)))
-
-  (.:.) (Trafo2 sb) (Trafo2 sa) = 
-    Trafo2 
-    (\m1 ->
-       case sa m1 of 
-        TrafoE2 m2 f1 -> case sb m2 of 
-         TrafoE2 m3 f2 -> 
-           TrafoE2  
-           m3 
-           (\a t3s e1 u1 -> let  (b, t1s, e2, u2) = f1 a t2s e1 u1
-                                 (c, t2s, e3, u3) = f2 b t3s e2 u2
-                            in   (c, t1s, e3, u3)
-           ))
-
-
-(>>>>) :: Category2 cat => cat a b -> cat b c -> cat a c
-f >>>> g = g .:. f
-
- 
-instance Arrow2 (Trafo2 m t) where
-  arr2 f 
-    =  Trafo2  (\m -> TrafoE2 m (\a t e u -> (f a, t, e, u)) )
-
-  
-  first2 (Trafo2 s) 
-    =  Trafo2
-       (\m1 -> case s m1 of
-          TrafoE2 m2 f -> 
-             TrafoE2  m2
-                    (\(P (a, c)) t2s e1 u1 -> 
-                                      let (b,t12,e2,u2) = f a t2s e1 u1 
-                                      in  (P (b, c),t12,e2,u2)
-                    )              
-       ) 
-
-  second2 f = arr2 swap >>>> first2 f >>>> arr2 swap
-              where   swap ~(P (x, y)) = P (y, x)
-             
-  f **** g =  first2 f >>>> second2 g  
- 
-  f &&&& g = arr2 (\b -> P (b, b)) >>>> (f **** g)      
-
-
-instance ArrowLoop2 (Trafo2 m t) where
-  loop2 (Trafo2 st) =
-    Trafo2 
-    (\m -> case st m of
-            TrafoE2 m1 f1 ->
-             TrafoE2  m1
-             (\a t e u -> 
-               let (P (b, x),t1,e1,u1) = f1 (P (a, x)) t e u                                                                            
-               in (b,t1,e1,u1)
-             ) 
-    )
-
-
-newtype List a s = List [a s]
-
--- | The combinator 'sequenceA2' sequentially composes a list
---   of 'Trafo2's into a 'Trafo2' that yields a 'List' of outputs.
---   Its use is analogous to the combinator 'sequence' combinator
---   for 'Monad's.
-sequenceA2 :: [Trafo2 m t a b] -> Trafo2 m t a (List b)
-sequenceA2 [] = arr2 (const (List []))
-sequenceA2 (x:xs) 
-       =  (x &&&& sequenceA2 xs) >>>> 
-          arr2 (\(P (a,List as)) -> List (a:as))
-