{-# LANGUAGE RankNTypes, CPP #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Data.Generics.Aliases
-- Copyright   :  (c) The University of Glasgow, CWI 2001--2004
-- License     :  BSD-style (see the LICENSE file)
-- 
-- Maintainer  :  generics@haskell.org
-- Stability   :  experimental
-- Portability :  non-portable (local universal quantification)
--
-- \"Scrap your boilerplate\" --- Generic programming in Haskell 
-- See <http://www.cs.uu.nl/wiki/GenericProgramming/SYB>.
-- The present module provides a number of declarations for typical generic
-- function types, corresponding type case, and others.
--
-----------------------------------------------------------------------------

module Data.Generics.Aliases (

        -- * Combinators to \"make\" generic functions via cast
        mkT, mkQ, mkM, mkMp, mkR,
        ext0, extT, extQ, extM, extMp, extB, extR,

        -- * Type synonyms for generic function types
        GenericT,
        GenericQ,
        GenericM,
        GenericB,
        GenericR,
        Generic,
        Generic'(..),
        GenericT'(..),
        GenericQ'(..),
        GenericM'(..),

        -- * Ingredients of generic functions
        orElse,

        -- * Function combinators on generic functions
        recoverMp,
        recoverQ,
        choiceMp,
        choiceQ,

        -- * Type extension for unary type constructors
        ext1,
        ext1T,
        ext1M,
        ext1Q,
        ext1R,
        ext1B,

        -- * Type extension for binary type constructors
        ext2T,
        ext2M,
        ext2Q,
        ext2R,
        ext2B

  ) where

#ifdef __HADDOCK__
import Prelude
#endif
import Control.Monad
import Data.Data

------------------------------------------------------------------------------
--
--      Combinators to "make" generic functions
--      We use type-safe cast in a number of ways to make generic functions.
--
------------------------------------------------------------------------------

-- | Make a generic transformation;
--   start from a type-specific case;
--   preserve the term otherwise
--
mkT :: ( Typeable a
       , Typeable b
       )
    => (b -> b)
    -> a
    -> a
mkT :: (b -> b) -> a -> a
mkT = (a -> a) -> (b -> b) -> a -> a
forall a b.
(Typeable a, Typeable b) =>
(a -> a) -> (b -> b) -> a -> a
extT a -> a
forall a. a -> a
id


-- | Make a generic query;
--   start from a type-specific case;
--   return a constant otherwise
--
mkQ :: ( Typeable a
       , Typeable b
       )
    => r
    -> (b -> r)
    -> a
    -> r
(r
r mkQ :: r -> (b -> r) -> a -> r
`mkQ` b -> r
br) a
a = case a -> Maybe b
forall a b. (Typeable a, Typeable b) => a -> Maybe b
cast a
a of
                        Just b
b  -> b -> r
br b
b
                        Maybe b
Nothing -> r
r


-- | Make a generic monadic transformation;
--   start from a type-specific case;
--   resort to return otherwise
--
mkM :: ( Monad m
       , Typeable a
       , Typeable b
       )
    => (b -> m b)
    -> a
    -> m a
mkM :: (b -> m b) -> a -> m a
mkM = (a -> m a) -> (b -> m b) -> a -> m a
forall (m :: * -> *) a b.
(Monad m, Typeable a, Typeable b) =>
(a -> m a) -> (b -> m b) -> a -> m a
extM a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return


{-

For the remaining definitions, we stick to a more concise style, i.e.,
we fold maybes with "maybe" instead of case ... of ..., and we also
use a point-free style whenever possible.

-}


-- | Make a generic monadic transformation for MonadPlus;
--   use \"const mzero\" (i.e., failure) instead of return as default.
--
mkMp :: ( MonadPlus m
        , Typeable a
        , Typeable b
        )
     => (b -> m b)
     -> a
     -> m a
mkMp :: (b -> m b) -> a -> m a
mkMp = (a -> m a) -> (b -> m b) -> a -> m a
forall (m :: * -> *) a b.
(Monad m, Typeable a, Typeable b) =>
(a -> m a) -> (b -> m b) -> a -> m a
extM (m a -> a -> m a
forall a b. a -> b -> a
const m a
forall (m :: * -> *) a. MonadPlus m => m a
mzero)


-- | Make a generic builder;
--   start from a type-specific ase;
--   resort to no build (i.e., mzero) otherwise
--
mkR :: ( MonadPlus m
       , Typeable a
       , Typeable b
       )
    => m b -> m a
mkR :: m b -> m a
mkR m b
f = m a
forall (m :: * -> *) a. MonadPlus m => m a
mzero m a -> m b -> m a
forall (m :: * -> *) a b.
(Monad m, Typeable a, Typeable b) =>
m a -> m b -> m a
`extR` m b
f


-- | Flexible type extension
ext0 :: (Typeable a, Typeable b) => c a -> c b -> c a
ext0 :: c a -> c b -> c a
ext0 c a
def c b
ext = c a -> (c a -> c a) -> Maybe (c a) -> c a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe c a
def c a -> c a
forall a. a -> a
id (c b -> Maybe (c a)
forall k (a :: k) (b :: k) (c :: k -> *).
(Typeable a, Typeable b) =>
c a -> Maybe (c b)
gcast c b
ext)


-- | Extend a generic transformation by a type-specific case
extT :: ( Typeable a
        , Typeable b
        )
     => (a -> a)
     -> (b -> b)
     -> a
     -> a
extT :: (a -> a) -> (b -> b) -> a -> a
extT a -> a
def b -> b
ext = T a -> a -> a
forall x. T x -> x -> x
unT (((a -> a) -> T a
forall x. (x -> x) -> T x
T a -> a
def) T a -> T b -> T a
forall a b (c :: * -> *).
(Typeable a, Typeable b) =>
c a -> c b -> c a
`ext0` ((b -> b) -> T b
forall x. (x -> x) -> T x
T b -> b
ext))


-- | Extend a generic query by a type-specific case
extQ :: ( Typeable a
        , Typeable b
        )
     => (a -> q)
     -> (b -> q)
     -> a
     -> q
extQ :: (a -> q) -> (b -> q) -> a -> q
extQ a -> q
f b -> q
g a
a = q -> (b -> q) -> Maybe b -> q
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (a -> q
f a
a) b -> q
g (a -> Maybe b
forall a b. (Typeable a, Typeable b) => a -> Maybe b
cast a
a)


-- | Extend a generic monadic transformation by a type-specific case
extM :: ( Monad m
        , Typeable a
        , Typeable b
        )
     => (a -> m a) -> (b -> m b) -> a -> m a
extM :: (a -> m a) -> (b -> m b) -> a -> m a
extM a -> m a
def b -> m b
ext = M m a -> a -> m a
forall (m :: * -> *) x. M m x -> x -> m x
unM (((a -> m a) -> M m a
forall (m :: * -> *) x. (x -> m x) -> M m x
M a -> m a
def) M m a -> M m b -> M m a
forall a b (c :: * -> *).
(Typeable a, Typeable b) =>
c a -> c b -> c a
`ext0` ((b -> m b) -> M m b
forall (m :: * -> *) x. (x -> m x) -> M m x
M b -> m b
ext))


-- | Extend a generic MonadPlus transformation by a type-specific case
extMp :: ( MonadPlus m
         , Typeable a
         , Typeable b
         )
      => (a -> m a) -> (b -> m b) -> a -> m a
extMp :: (a -> m a) -> (b -> m b) -> a -> m a
extMp = (a -> m a) -> (b -> m b) -> a -> m a
forall (m :: * -> *) a b.
(Monad m, Typeable a, Typeable b) =>
(a -> m a) -> (b -> m b) -> a -> m a
extM


-- | Extend a generic builder
extB :: ( Typeable a
        , Typeable b
        )
     => a -> b -> a
extB :: a -> b -> a
extB a
a = a -> (a -> a) -> Maybe a -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
a a -> a
forall a. a -> a
id (Maybe a -> a) -> (b -> Maybe a) -> b -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Maybe a
forall a b. (Typeable a, Typeable b) => a -> Maybe b
cast


-- | Extend a generic reader
extR :: ( Monad m
        , Typeable a
        , Typeable b
        )
     => m a -> m b -> m a
extR :: m a -> m b -> m a
extR m a
def m b
ext = R m a -> m a
forall (m :: * -> *) x. R m x -> m x
unR ((m a -> R m a
forall (m :: * -> *) x. m x -> R m x
R m a
def) R m a -> R m b -> R m a
forall a b (c :: * -> *).
(Typeable a, Typeable b) =>
c a -> c b -> c a
`ext0` (m b -> R m b
forall (m :: * -> *) x. m x -> R m x
R m b
ext))



------------------------------------------------------------------------------
--
--      Type synonyms for generic function types
--
------------------------------------------------------------------------------


-- | Generic transformations,
--   i.e., take an \"a\" and return an \"a\"
--
type GenericT = forall a. Data a => a -> a


-- | Generic queries of type \"r\",
--   i.e., take any \"a\" and return an \"r\"
--
type GenericQ r = forall a. Data a => a -> r


-- | Generic monadic transformations,
--   i.e., take an \"a\" and compute an \"a\"
--
type GenericM m = forall a. Data a => a -> m a


-- | Generic builders
--   i.e., produce an \"a\".
--
type GenericB = forall a. Data a => a


-- | Generic readers, say monadic builders,
--   i.e., produce an \"a\" with the help of a monad \"m\".
--
type GenericR m = forall a. Data a => m a


-- | The general scheme underlying generic functions
--   assumed by gfoldl; there are isomorphisms such as
--   GenericT = Generic T.
--
type Generic c = forall a. Data a => a -> c a


-- | Wrapped generic functions;
--   recall: [Generic c] would be legal but [Generic' c] not.
--
data Generic' c = Generic' { Generic' c -> forall a. Data a => a -> c a
unGeneric' :: Generic c }


-- | Other first-class polymorphic wrappers
newtype GenericT'   = GT { GenericT' -> forall a. Data a => a -> a
unGT :: forall a. Data a => a -> a }
newtype GenericQ' r = GQ { GenericQ' r -> forall a. Data a => a -> r
unGQ :: GenericQ r }
newtype GenericM' m = GM { GenericM' m -> forall a. Data a => a -> m a
unGM :: forall a. Data a => a -> m a }


-- | Left-biased choice on maybes
orElse :: Maybe a -> Maybe a -> Maybe a
Maybe a
x orElse :: Maybe a -> Maybe a -> Maybe a
`orElse` Maybe a
y = case Maybe a
x of
                 Just a
_  -> Maybe a
x
                 Maybe a
Nothing -> Maybe a
y


{-

The following variations take "orElse" to the function
level. Furthermore, we generalise from "Maybe" to any
"MonadPlus". This makes sense for monadic transformations and
queries. We say that the resulting combinators modell choice. We also
provide a prime example of choice, that is, recovery from failure. In
the case of transformations, we recover via return whereas for
queries a given constant is returned.

-}

-- | Choice for monadic transformations
choiceMp :: MonadPlus m => GenericM m -> GenericM m -> GenericM m
choiceMp :: GenericM m -> GenericM m -> GenericM m
choiceMp GenericM m
f GenericM m
g a
x = a -> m a
GenericM m
f a
x m a -> m a -> m a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` a -> m a
GenericM m
g a
x


-- | Choice for monadic queries
choiceQ :: MonadPlus m => GenericQ (m r) -> GenericQ (m r) -> GenericQ (m r)
choiceQ :: GenericQ (m r) -> GenericQ (m r) -> GenericQ (m r)
choiceQ GenericQ (m r)
f GenericQ (m r)
g a
x = a -> m r
GenericQ (m r)
f a
x m r -> m r -> m r
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` a -> m r
GenericQ (m r)
g a
x


-- | Recover from the failure of monadic transformation by identity
recoverMp :: MonadPlus m => GenericM m -> GenericM m
recoverMp :: GenericM m -> GenericM m
recoverMp GenericM m
f = GenericM m
f GenericM m -> GenericM m -> GenericM m
forall (m :: * -> *).
MonadPlus m =>
GenericM m -> GenericM m -> GenericM m
`choiceMp` GenericM m
forall (m :: * -> *) a. Monad m => a -> m a
return


-- | Recover from the failure of monadic query by a constant
recoverQ :: MonadPlus m => r -> GenericQ (m r) -> GenericQ (m r)
recoverQ :: r -> GenericQ (m r) -> GenericQ (m r)
recoverQ r
r GenericQ (m r)
f = GenericQ (m r)
f GenericQ (m r) -> GenericQ (m r) -> GenericQ (m r)
forall (m :: * -> *) r.
MonadPlus m =>
GenericQ (m r) -> GenericQ (m r) -> GenericQ (m r)
`choiceQ` m r -> a -> m r
forall a b. a -> b -> a
const (r -> m r
forall (m :: * -> *) a. Monad m => a -> m a
return r
r)



------------------------------------------------------------------------------
--      Type extension for unary type constructors
------------------------------------------------------------------------------

#if __GLASGOW_HASKELL__ >= 707
#define Typeable1 Typeable
#define Typeable2 Typeable
#endif

-- | Flexible type extension
ext1 :: (Data a, Typeable1 t)
     => c a
     -> (forall d. Data d => c (t d))
     -> c a
ext1 :: c a -> (forall d. Data d => c (t d)) -> c a
ext1 c a
def forall d. Data d => c (t d)
ext = c a -> (c a -> c a) -> Maybe (c a) -> c a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe c a
def c a -> c a
forall a. a -> a
id ((forall d. Data d => c (t d)) -> Maybe (c a)
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c a)
dataCast1 forall d. Data d => c (t d)
ext)


-- | Type extension of transformations for unary type constructors
ext1T :: (Data d, Typeable1 t)
      => (forall e. Data e => e -> e)
      -> (forall f. Data f => t f -> t f)
      -> d -> d
ext1T :: (forall a. Data a => a -> a)
-> (forall f. Data f => t f -> t f) -> d -> d
ext1T forall a. Data a => a -> a
def forall f. Data f => t f -> t f
ext = T d -> d -> d
forall x. T x -> x -> x
unT (((d -> d) -> T d
forall x. (x -> x) -> T x
T d -> d
forall a. Data a => a -> a
def) T d -> (forall d. Data d => T (t d)) -> T d
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
c a -> (forall d. Data d => c (t d)) -> c a
`ext1` ((t d -> t d) -> T (t d)
forall x. (x -> x) -> T x
T t d -> t d
forall f. Data f => t f -> t f
ext))


-- | Type extension of monadic transformations for type constructors
ext1M :: (Monad m, Data d, Typeable1 t)
      => (forall e. Data e => e -> m e)
      -> (forall f. Data f => t f -> m (t f))
      -> d -> m d
ext1M :: (forall e. Data e => e -> m e)
-> (forall f. Data f => t f -> m (t f)) -> d -> m d
ext1M forall e. Data e => e -> m e
def forall f. Data f => t f -> m (t f)
ext = M m d -> d -> m d
forall (m :: * -> *) x. M m x -> x -> m x
unM (((d -> m d) -> M m d
forall (m :: * -> *) x. (x -> m x) -> M m x
M d -> m d
forall e. Data e => e -> m e
def) M m d -> (forall d. Data d => M m (t d)) -> M m d
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
c a -> (forall d. Data d => c (t d)) -> c a
`ext1` ((t d -> m (t d)) -> M m (t d)
forall (m :: * -> *) x. (x -> m x) -> M m x
M t d -> m (t d)
forall f. Data f => t f -> m (t f)
ext))


-- | Type extension of queries for type constructors
ext1Q :: (Data d, Typeable1 t)
      => (d -> q)
      -> (forall e. Data e => t e -> q)
      -> d -> q
ext1Q :: (d -> q) -> (forall e. Data e => t e -> q) -> d -> q
ext1Q d -> q
def forall e. Data e => t e -> q
ext = Q q d -> d -> q
forall q x. Q q x -> x -> q
unQ (((d -> q) -> Q q d
forall q x. (x -> q) -> Q q x
Q d -> q
def) Q q d -> (forall d. Data d => Q q (t d)) -> Q q d
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
c a -> (forall d. Data d => c (t d)) -> c a
`ext1` ((t d -> q) -> Q q (t d)
forall q x. (x -> q) -> Q q x
Q t d -> q
forall e. Data e => t e -> q
ext))


-- | Type extension of readers for type constructors
ext1R :: (Monad m, Data d, Typeable1 t)
      => m d
      -> (forall e. Data e => m (t e))
      -> m d
ext1R :: m d -> (forall e. Data e => m (t e)) -> m d
ext1R m d
def forall e. Data e => m (t e)
ext = R m d -> m d
forall (m :: * -> *) x. R m x -> m x
unR ((m d -> R m d
forall (m :: * -> *) x. m x -> R m x
R m d
def) R m d -> (forall d. Data d => R m (t d)) -> R m d
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
c a -> (forall d. Data d => c (t d)) -> c a
`ext1` (m (t d) -> R m (t d)
forall (m :: * -> *) x. m x -> R m x
R m (t d)
forall e. Data e => m (t e)
ext))


-- | Type extension of builders for type constructors
ext1B :: (Data a, Typeable1 t)
      => a
      -> (forall b. Data b => (t b))
      -> a
ext1B :: a -> (forall b. Data b => t b) -> a
ext1B a
def forall b. Data b => t b
ext = B a -> a
forall x. B x -> x
unB ((a -> B a
forall x. x -> B x
B a
def) B a -> (forall d. Data d => B (t d)) -> B a
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
c a -> (forall d. Data d => c (t d)) -> c a
`ext1` (t d -> B (t d)
forall x. x -> B x
B t d
forall b. Data b => t b
ext))

------------------------------------------------------------------------------
--      Type extension for binary type constructors
------------------------------------------------------------------------------

-- | Flexible type extension
ext2 :: (Data a, Typeable2 t)
     => c a
     -> (forall d1 d2. (Data d1, Data d2) => c (t d1 d2))
     -> c a
ext2 :: c a -> (forall d1 d2. (Data d1, Data d2) => c (t d1 d2)) -> c a
ext2 c a
def forall d1 d2. (Data d1, Data d2) => c (t d1 d2)
ext = c a -> (c a -> c a) -> Maybe (c a) -> c a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe c a
def c a -> c a
forall a. a -> a
id ((forall d1 d2. (Data d1, Data d2) => c (t d1 d2)) -> Maybe (c a)
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a)
dataCast2 forall d1 d2. (Data d1, Data d2) => c (t d1 d2)
ext)


-- | Type extension of transformations for unary type constructors
ext2T :: (Data d, Typeable2 t)
      => (forall e. Data e => e -> e)
      -> (forall d1 d2. (Data d1, Data d2) => t d1 d2 -> t d1 d2)
      -> d -> d
ext2T :: (forall a. Data a => a -> a)
-> (forall d1 d2. (Data d1, Data d2) => t d1 d2 -> t d1 d2)
-> d
-> d
ext2T forall a. Data a => a -> a
def forall d1 d2. (Data d1, Data d2) => t d1 d2 -> t d1 d2
ext = T d -> d -> d
forall x. T x -> x -> x
unT (((d -> d) -> T d
forall x. (x -> x) -> T x
T d -> d
forall a. Data a => a -> a
def) T d -> (forall d1 d2. (Data d1, Data d2) => T (t d1 d2)) -> T d
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
c a -> (forall d1 d2. (Data d1, Data d2) => c (t d1 d2)) -> c a
`ext2` ((t d1 d2 -> t d1 d2) -> T (t d1 d2)
forall x. (x -> x) -> T x
T t d1 d2 -> t d1 d2
forall d1 d2. (Data d1, Data d2) => t d1 d2 -> t d1 d2
ext))


-- | Type extension of monadic transformations for type constructors
ext2M :: (Monad m, Data d, Typeable2 t)
      => (forall e. Data e => e -> m e)
      -> (forall d1 d2. (Data d1, Data d2) => t d1 d2 -> m (t d1 d2))
      -> d -> m d
ext2M :: (forall e. Data e => e -> m e)
-> (forall d1 d2. (Data d1, Data d2) => t d1 d2 -> m (t d1 d2))
-> d
-> m d
ext2M forall e. Data e => e -> m e
def forall d1 d2. (Data d1, Data d2) => t d1 d2 -> m (t d1 d2)
ext = M m d -> d -> m d
forall (m :: * -> *) x. M m x -> x -> m x
unM (((d -> m d) -> M m d
forall (m :: * -> *) x. (x -> m x) -> M m x
M d -> m d
forall e. Data e => e -> m e
def) M m d
-> (forall d1 d2. (Data d1, Data d2) => M m (t d1 d2)) -> M m d
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
c a -> (forall d1 d2. (Data d1, Data d2) => c (t d1 d2)) -> c a
`ext2` ((t d1 d2 -> m (t d1 d2)) -> M m (t d1 d2)
forall (m :: * -> *) x. (x -> m x) -> M m x
M t d1 d2 -> m (t d1 d2)
forall d1 d2. (Data d1, Data d2) => t d1 d2 -> m (t d1 d2)
ext))


-- | Type extension of queries for type constructors
ext2Q :: (Data d, Typeable2 t)
      => (d -> q)
      -> (forall d1 d2. (Data d1, Data d2) => t d1 d2 -> q)
      -> d -> q
ext2Q :: (d -> q)
-> (forall d1 d2. (Data d1, Data d2) => t d1 d2 -> q) -> d -> q
ext2Q d -> q
def forall d1 d2. (Data d1, Data d2) => t d1 d2 -> q
ext = Q q d -> d -> q
forall q x. Q q x -> x -> q
unQ (((d -> q) -> Q q d
forall q x. (x -> q) -> Q q x
Q d -> q
def) Q q d
-> (forall d1 d2. (Data d1, Data d2) => Q q (t d1 d2)) -> Q q d
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
c a -> (forall d1 d2. (Data d1, Data d2) => c (t d1 d2)) -> c a
`ext2` ((t d1 d2 -> q) -> Q q (t d1 d2)
forall q x. (x -> q) -> Q q x
Q t d1 d2 -> q
forall d1 d2. (Data d1, Data d2) => t d1 d2 -> q
ext))


-- | Type extension of readers for type constructors
ext2R :: (Monad m, Data d, Typeable2 t)
      => m d
      -> (forall d1 d2. (Data d1, Data d2) => m (t d1 d2))
      -> m d
ext2R :: m d -> (forall d1 d2. (Data d1, Data d2) => m (t d1 d2)) -> m d
ext2R m d
def forall d1 d2. (Data d1, Data d2) => m (t d1 d2)
ext = R m d -> m d
forall (m :: * -> *) x. R m x -> m x
unR ((m d -> R m d
forall (m :: * -> *) x. m x -> R m x
R m d
def) R m d
-> (forall d1 d2. (Data d1, Data d2) => R m (t d1 d2)) -> R m d
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
c a -> (forall d1 d2. (Data d1, Data d2) => c (t d1 d2)) -> c a
`ext2` (m (t d1 d2) -> R m (t d1 d2)
forall (m :: * -> *) x. m x -> R m x
R m (t d1 d2)
forall d1 d2. (Data d1, Data d2) => m (t d1 d2)
ext))


-- | Type extension of builders for type constructors
ext2B :: (Data a, Typeable2 t)
      => a
      -> (forall d1 d2. (Data d1, Data d2) => (t d1 d2))
      -> a
ext2B :: a -> (forall d1 d2. (Data d1, Data d2) => t d1 d2) -> a
ext2B a
def forall d1 d2. (Data d1, Data d2) => t d1 d2
ext = B a -> a
forall x. B x -> x
unB ((a -> B a
forall x. x -> B x
B a
def) B a -> (forall d1 d2. (Data d1, Data d2) => B (t d1 d2)) -> B a
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
c a -> (forall d1 d2. (Data d1, Data d2) => c (t d1 d2)) -> c a
`ext2` (t d1 d2 -> B (t d1 d2)
forall x. x -> B x
B t d1 d2
forall d1 d2. (Data d1, Data d2) => t d1 d2
ext))

------------------------------------------------------------------------------
--
--      Type constructors for type-level lambdas
--
------------------------------------------------------------------------------


-- | The type constructor for transformations
newtype T x = T { T x -> x -> x
unT :: x -> x }

-- | The type constructor for transformations
newtype M m x = M { M m x -> x -> m x
unM :: x -> m x }

-- | The type constructor for queries
newtype Q q x = Q { Q q x -> x -> q
unQ :: x -> q }

-- | The type constructor for readers
newtype R m x = R { R m x -> m x
unR :: m x }

-- | The type constructor for builders
newtype B x = B {B x -> x
unB :: x}