    {-# LANGUAGE DataKinds #-}
    {-# LANGUAGE DeriveFunctor #-}
    {-# LANGUAGE GADTs #-}
    {-# LANGUAGE PolyKinds #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE StandaloneDeriving #-}
    {-# LANGUAGE TypeFamilies #-}
    module GHC.Cmm.Dataflow.Block
        ( Extensibility (..)
        , O
        , C
        , MaybeO(..)
        , IndexedCO
        , Block(..)
        , blockAppend
        , blockConcat
        , blockCons
        , blockFromList
        , blockJoin
        , blockJoinHead
        , blockJoinTail
        , blockSnoc
        , blockSplit
        , blockSplitHead
        , blockSplitTail
        , blockToList
        , emptyBlock
        , firstNode
        , foldBlockNodesB
        , foldBlockNodesB3
        , foldBlockNodesF
        , isEmptyBlock
        , lastNode
        , mapBlock
        , mapBlock'
        , mapBlock3'
        , replaceFirstNode
        , replaceLastNode
        ) where

    import GHC.Prelude

    -- -----------------------------------------------------------------------------
    -- Shapes: Open and Closed

    -- | Used at the type level to indicate "open" vs "closed" structure.
    data Extensibility
      -- | An "open" structure with a unique, unnamed control-flow edge flowing in
      -- or out. \"Fallthrough\" and concatenation are permitted at an open point.
      = Open
      -- | A "closed" structure which supports control transfer only through the use
      -- of named labels---no "fallthrough" is permitted. The number of control-flow
      -- edges is unconstrained.
      | Closed

    type O = 'Open
    type C = 'Closed

    -- | Either type indexed by closed/open using type families
    type family IndexedCO (ex :: Extensibility) (a :: k) (b :: k) :: k
    type instance IndexedCO C a _b = a
    type instance IndexedCO O _a b = b

    -- | Maybe type indexed by open/closed
    data MaybeO ex t where
      JustO    :: t -> MaybeO O t
      NothingO ::      MaybeO C t

    deriving instance Functor (MaybeO ex)

    -- -----------------------------------------------------------------------------
    -- The Block type

    -- | A sequence of nodes.  May be any of four shapes (O/O, O/C, C/O, C/C).
    -- Open at the entry means single entry, mutatis mutandis for exit.
    -- A closed/closed block is a /basic/ block and can't be extended further.
    -- Clients should avoid manipulating blocks and should stick to either nodes
    -- or graphs.
    data Block n e x where
      BlockCO  :: n C O -> Block n O O          -> Block n C O
      BlockCC  :: n C O -> Block n O O -> n O C -> Block n C C
      BlockOC  ::          Block n O O -> n O C -> Block n O C

      BNil    :: Block n O O
      BMiddle :: n O O                      -> Block n O O
      BCat    :: Block n O O -> Block n O O -> Block n O O
      BSnoc   :: Block n O O -> n O O       -> Block n O O
      BCons   :: n O O       -> Block n O O -> Block n O O

    -- -----------------------------------------------------------------------------
    -- Simple operations on Blocks

    -- Predicates

    isEmptyBlock :: Block n e x -> Bool
    isEmptyBlock :: forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e x -> Bool
    isEmptyBlock Block n e x
    BNil       = Bool
    True
    isEmptyBlock (BCat Block n 'Open 'Open
    l Block n 'Open 'Open
    r) = Block n 'Open 'Open -> Bool
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e x -> Bool
    isEmptyBlock Block n 'Open 'Open
    l Bool -> Bool -> Bool
    && Block n 'Open 'Open -> Bool
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e x -> Bool
    isEmptyBlock Block n 'Open 'Open
    r
    isEmptyBlock Block n e x
    _          = Bool
    False

    -- Building

    emptyBlock :: Block n O O
    emptyBlock :: forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open
    emptyBlock = Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open
    BNil

    blockCons :: n O O -> Block n O x -> Block n O x
    blockCons :: forall (n :: Extensibility -> Extensibility -> *)
           (x :: Extensibility).
    n 'Open 'Open -> Block n 'Open x -> Block n 'Open x
    blockCons n 'Open 'Open
    n Block n 'Open x
    b = case Block n 'Open x
    b of
      BlockOC Block n 'Open 'Open
    b n 'Open 'Closed
    l  -> (Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open x
    Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    BlockOC (Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open x)
    -> Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open x
    forall a b. (a -> b) -> a -> b
    $! (n 'Open 'Open
    n n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (x :: Extensibility).
    n 'Open 'Open -> Block n 'Open x -> Block n 'Open x
    `blockCons` Block n 'Open 'Open
    b)) n 'Open 'Closed
    l
      BNil{}    -> n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Open 'Open -> Block n 'Open 'Open
    BMiddle n 'Open 'Open
    n
      BMiddle{} -> n 'Open 'Open
    n n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    `BCons` Block n 'Open x
    Block n 'Open 'Open
    b
      BCat{}    -> n 'Open 'Open
    n n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    `BCons` Block n 'Open x
    Block n 'Open 'Open
    b
      BSnoc{}   -> n 'Open 'Open
    n n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    `BCons` Block n 'Open x
    Block n 'Open 'Open
    b
      BCons{}   -> n 'Open 'Open
    n n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    `BCons` Block n 'Open x
    Block n 'Open 'Open
    b

    blockSnoc :: Block n e O -> n O O -> Block n e O
    blockSnoc :: forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility).
    Block n e 'Open -> n 'Open 'Open -> Block n e 'Open
    blockSnoc Block n e 'Open
    b n 'Open 'Open
    n = case Block n e 'Open
    b of
      BlockCO n 'Closed 'Open
    f Block n 'Open 'Open
    b -> n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    BlockCO n 'Closed 'Open
    f (Block n 'Open 'Open -> Block n e 'Open)
    -> Block n 'Open 'Open -> Block n e 'Open
    forall a b. (a -> b) -> a -> b
    $! (Block n 'Open 'Open
    b Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility).
    Block n e 'Open -> n 'Open 'Open -> Block n e 'Open
    `blockSnoc` n 'Open 'Open
    n)
      BNil{}      -> n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Open 'Open -> Block n 'Open 'Open
    BMiddle n 'Open 'Open
    n
      BMiddle{}   -> Block n e 'Open
    Block n 'Open 'Open
    b Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    `BSnoc` n 'Open 'Open
    n
      BCat{}      -> Block n e 'Open
    Block n 'Open 'Open
    b Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    `BSnoc` n 'Open 'Open
    n
      BSnoc{}     -> Block n e 'Open
    Block n 'Open 'Open
    b Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    `BSnoc` n 'Open 'Open
    n
      BCons{}     -> Block n e 'Open
    Block n 'Open 'Open
    b Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    `BSnoc` n 'Open 'Open
    n

    blockJoinHead :: n C O -> Block n O x -> Block n C x
    blockJoinHead :: forall (n :: Extensibility -> Extensibility -> *)
           (x :: Extensibility).
    n 'Closed 'Open -> Block n 'Open x -> Block n 'Closed x
    blockJoinHead n 'Closed 'Open
    f (BlockOC Block n 'Open 'Open
    b n 'Open 'Closed
    l) = n 'Closed 'Open
    -> Block n 'Open 'Open
    -> n 'Open 'Closed
    -> Block n 'Closed 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open
    -> Block n 'Open 'Open
    -> n 'Open 'Closed
    -> Block n 'Closed 'Closed
    BlockCC n 'Closed 'Open
    f Block n 'Open 'Open
    b n 'Open 'Closed
    l
    blockJoinHead n 'Closed 'Open
    f Block n 'Open x
    b = n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    BlockCO n 'Closed 'Open
    f Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open
    BNil Block n 'Closed 'Open -> Block n 'Open x -> Block n 'Closed x
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e 'Open -> Block n 'Open x -> Block n e x
    `cat` Block n 'Open x
    b

    blockJoinTail :: Block n e O -> n O C -> Block n e C
    blockJoinTail :: forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility).
    Block n e 'Open -> n 'Open 'Closed -> Block n e 'Closed
    blockJoinTail (BlockCO n 'Closed 'Open
    f Block n 'Open 'Open
    b) n 'Open 'Closed
    t = n 'Closed 'Open
    -> Block n 'Open 'Open
    -> n 'Open 'Closed
    -> Block n 'Closed 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open
    -> Block n 'Open 'Open
    -> n 'Open 'Closed
    -> Block n 'Closed 'Closed
    BlockCC n 'Closed 'Open
    f Block n 'Open 'Open
    b n 'Open 'Closed
    t
    blockJoinTail Block n e 'Open
    b n 'Open 'Closed
    t = Block n e 'Open
    b Block n e 'Open -> Block n 'Open 'Closed -> Block n e 'Closed
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e 'Open -> Block n 'Open x -> Block n e x
    `cat` Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    BlockOC Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open
    BNil n 'Open 'Closed
    t

    blockJoin :: n C O -> Block n O O -> n O C -> Block n C C
    blockJoin :: forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open
    -> Block n 'Open 'Open
    -> n 'Open 'Closed
    -> Block n 'Closed 'Closed
    blockJoin n 'Closed 'Open
    f Block n 'Open 'Open
    b n 'Open 'Closed
    t = n 'Closed 'Open
    -> Block n 'Open 'Open
    -> n 'Open 'Closed
    -> Block n 'Closed 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open
    -> Block n 'Open 'Open
    -> n 'Open 'Closed
    -> Block n 'Closed 'Closed
    BlockCC n 'Closed 'Open
    f Block n 'Open 'Open
    b n 'Open 'Closed
    t

    blockAppend :: Block n e O -> Block n O x -> Block n e x
    blockAppend :: forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e 'Open -> Block n 'Open x -> Block n e x
    blockAppend = Block n e 'Open -> Block n 'Open x -> Block n e x
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e 'Open -> Block n 'Open x -> Block n e x
    cat

    blockConcat :: [Block n O O] -> Block n O O
    blockConcat :: forall (n :: Extensibility -> Extensibility -> *).
    [Block n 'Open 'Open] -> Block n 'Open 'Open
    blockConcat = (Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open)
    -> Block n 'Open 'Open
    -> [Block n 'Open 'Open]
    -> Block n 'Open 'Open
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e 'Open -> Block n 'Open x -> Block n e x
    blockAppend Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open
    emptyBlock

    -- Taking apart

    firstNode :: Block n C x -> n C O
    firstNode :: forall (n :: Extensibility -> Extensibility -> *)
           (x :: Extensibility).
    Block n 'Closed x -> n 'Closed 'Open
    firstNode (BlockCO n 'Closed 'Open
    n Block n 'Open 'Open
    _)   = n 'Closed 'Open
    n
    firstNode (BlockCC n 'Closed 'Open
    n Block n 'Open 'Open
    _ n 'Open 'Closed
    _) = n 'Closed 'Open
    n

    lastNode :: Block n x C -> n O C
    lastNode :: forall (n :: Extensibility -> Extensibility -> *)
           (x :: Extensibility).
    Block n x 'Closed -> n 'Open 'Closed
    lastNode (BlockOC   Block n 'Open 'Open
    _ n 'Open 'Closed
    n) = n 'Open 'Closed
    n
    lastNode (BlockCC n 'Closed 'Open
    _ Block n 'Open 'Open
    _ n 'Open 'Closed
    n) = n 'Open 'Closed
    n

    blockSplitHead :: Block n C x -> (n C O, Block n O x)
    blockSplitHead :: forall (n :: Extensibility -> Extensibility -> *)
           (x :: Extensibility).
    Block n 'Closed x -> (n 'Closed 'Open, Block n 'Open x)
    blockSplitHead (BlockCO n 'Closed 'Open
    n Block n 'Open 'Open
    b)   = (n 'Closed 'Open
    n, Block n 'Open x
    Block n 'Open 'Open
    b)
    blockSplitHead (BlockCC n 'Closed 'Open
    n Block n 'Open 'Open
    b n 'Open 'Closed
    t) = (n 'Closed 'Open
    n, Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    BlockOC Block n 'Open 'Open
    b n 'Open 'Closed
    t)

    blockSplitTail :: Block n e C -> (Block n e O, n O C)
    blockSplitTail :: forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility).
    Block n e 'Closed -> (Block n e 'Open, n 'Open 'Closed)
    blockSplitTail (BlockOC Block n 'Open 'Open
    b n 'Open 'Closed
    n)   = (Block n e 'Open
    Block n 'Open 'Open
    b, n 'Open 'Closed
    n)
    blockSplitTail (BlockCC n 'Closed 'Open
    f Block n 'Open 'Open
    b n 'Open 'Closed
    t) = (n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    BlockCO n 'Closed 'Open
    f Block n 'Open 'Open
    b, n 'Open 'Closed
    t)

    -- | Split a closed block into its entry node, open middle block, and
    -- exit node.
    blockSplit :: Block n C C -> (n C O, Block n O O, n O C)
    blockSplit :: forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Closed 'Closed
    -> (n 'Closed 'Open, Block n 'Open 'Open, n 'Open 'Closed)
    blockSplit (BlockCC n 'Closed 'Open
    f Block n 'Open 'Open
    b n 'Open 'Closed
    t) = (n 'Closed 'Open
    f, Block n 'Open 'Open
    b, n 'Open 'Closed
    t)

    blockToList :: Block n O O -> [n O O]
    blockToList :: forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> [n 'Open 'Open]
    blockToList Block n 'Open 'Open
    b = Block n 'Open 'Open -> [n 'Open 'Open] -> [n 'Open 'Open]
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> [n 'Open 'Open] -> [n 'Open 'Open]
    go Block n 'Open 'Open
    b []
       where go :: Block n O O -> [n O O] -> [n O O]
             go :: forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> [n 'Open 'Open] -> [n 'Open 'Open]
    go Block n 'Open 'Open
    BNil         [n 'Open 'Open]
    r = [n 'Open 'Open]
    r
             go (BMiddle n 'Open 'Open
    n)  [n 'Open 'Open]
    r = n 'Open 'Open
    n n 'Open 'Open -> [n 'Open 'Open] -> [n 'Open 'Open]
    forall a. a -> [a] -> [a]
    : [n 'Open 'Open]
    r
             go (BCat Block n 'Open 'Open
    b1 Block n 'Open 'Open
    b2) [n 'Open 'Open]
    r = Block n 'Open 'Open -> [n 'Open 'Open] -> [n 'Open 'Open]
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> [n 'Open 'Open] -> [n 'Open 'Open]
    go Block n 'Open 'Open
    b1 ([n 'Open 'Open] -> [n 'Open 'Open])
    -> [n 'Open 'Open] -> [n 'Open 'Open]
    forall a b. (a -> b) -> a -> b
    $! Block n 'Open 'Open -> [n 'Open 'Open] -> [n 'Open 'Open]
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> [n 'Open 'Open] -> [n 'Open 'Open]
    go Block n 'Open 'Open
    b2 [n 'Open 'Open]
    r
             go (BSnoc Block n 'Open 'Open
    b1 n 'Open 'Open
    n) [n 'Open 'Open]
    r = Block n 'Open 'Open -> [n 'Open 'Open] -> [n 'Open 'Open]
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> [n 'Open 'Open] -> [n 'Open 'Open]
    go Block n 'Open 'Open
    b1 (n 'Open 'Open
    nn 'Open 'Open -> [n 'Open 'Open] -> [n 'Open 'Open]
    forall a. a -> [a] -> [a]
    :[n 'Open 'Open]
    r)
             go (BCons n 'Open 'Open
    n Block n 'Open 'Open
    b1) [n 'Open 'Open]
    r = n 'Open 'Open
    n n 'Open 'Open -> [n 'Open 'Open] -> [n 'Open 'Open]
    forall a. a -> [a] -> [a]
    : Block n 'Open 'Open -> [n 'Open 'Open] -> [n 'Open 'Open]
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> [n 'Open 'Open] -> [n 'Open 'Open]
    go Block n 'Open 'Open
    b1 [n 'Open 'Open]
    r

    blockFromList :: [n O O] -> Block n O O
    blockFromList :: forall (n :: Extensibility -> Extensibility -> *).
    [n 'Open 'Open] -> Block n 'Open 'Open
    blockFromList = (n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open)
    -> Block n 'Open 'Open -> [n 'Open 'Open] -> Block n 'Open 'Open
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCons Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open
    BNil

    -- Modifying

    replaceFirstNode :: Block n C x -> n C O -> Block n C x
    replaceFirstNode :: forall (n :: Extensibility -> Extensibility -> *)
           (x :: Extensibility).
    Block n 'Closed x -> n 'Closed 'Open -> Block n 'Closed x
    replaceFirstNode (BlockCO n 'Closed 'Open
    _ Block n 'Open 'Open
    b)   n 'Closed 'Open
    f = n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    BlockCO n 'Closed 'Open
    f Block n 'Open 'Open
    b
    replaceFirstNode (BlockCC n 'Closed 'Open
    _ Block n 'Open 'Open
    b n 'Open 'Closed
    n) n 'Closed 'Open
    f = n 'Closed 'Open
    -> Block n 'Open 'Open
    -> n 'Open 'Closed
    -> Block n 'Closed 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open
    -> Block n 'Open 'Open
    -> n 'Open 'Closed
    -> Block n 'Closed 'Closed
    BlockCC n 'Closed 'Open
    f Block n 'Open 'Open
    b n 'Open 'Closed
    n

    replaceLastNode :: Block n x C -> n O C -> Block n x C
    replaceLastNode :: forall (n :: Extensibility -> Extensibility -> *)
           (x :: Extensibility).
    Block n x 'Closed -> n 'Open 'Closed -> Block n x 'Closed
    replaceLastNode (BlockOC   Block n 'Open 'Open
    b n 'Open 'Closed
    _) n 'Open 'Closed
    n = Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    BlockOC Block n 'Open 'Open
    b n 'Open 'Closed
    n
    replaceLastNode (BlockCC n 'Closed 'Open
    l Block n 'Open 'Open
    b n 'Open 'Closed
    _) n 'Open 'Closed
    n = n 'Closed 'Open
    -> Block n 'Open 'Open
    -> n 'Open 'Closed
    -> Block n 'Closed 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open
    -> Block n 'Open 'Open
    -> n 'Open 'Closed
    -> Block n 'Closed 'Closed
    BlockCC n 'Closed 'Open
    l Block n 'Open 'Open
    b n 'Open 'Closed
    n

    -- -----------------------------------------------------------------------------
    -- General concatenation

    cat :: Block n e O -> Block n O x -> Block n e x
    cat :: forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e 'Open -> Block n 'Open x -> Block n e x
    cat Block n e 'Open
    x Block n 'Open x
    y = case Block n e 'Open
    x of
      Block n e 'Open
    BNil -> Block n e x
    Block n 'Open x
    y

      BlockCO n 'Closed 'Open
    l Block n 'Open 'Open
    b1 -> case Block n 'Open x
    y of
                       BlockOC Block n 'Open 'Open
    b2 n 'Open 'Closed
    n -> (n 'Closed 'Open
    -> Block n 'Open 'Open
    -> n 'Open 'Closed
    -> Block n 'Closed 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open
    -> Block n 'Open 'Open
    -> n 'Open 'Closed
    -> Block n 'Closed 'Closed
    BlockCC n 'Closed 'Open
    l (Block n 'Open 'Open -> n 'Open 'Closed -> Block n e x)
    -> Block n 'Open 'Open -> n 'Open 'Closed -> Block n e x
    forall a b. (a -> b) -> a -> b
    $! (Block n 'Open 'Open
    b1 Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e 'Open -> Block n 'Open x -> Block n e x
    `cat` Block n 'Open 'Open
    b2)) n 'Open 'Closed
    n
                       Block n 'Open x
    BNil         -> Block n e x
    Block n e 'Open
    x
                       BMiddle n 'Open 'Open
    _    -> n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    BlockCO n 'Closed 'Open
    l (Block n 'Open 'Open -> Block n e x)
    -> Block n 'Open 'Open -> Block n e x
    forall a b. (a -> b) -> a -> b
    $! (Block n 'Open 'Open
    b1 Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e 'Open -> Block n 'Open x -> Block n e x
    `cat` Block n 'Open x
    Block n 'Open 'Open
    y)
                       BCat{}       -> n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    BlockCO n 'Closed 'Open
    l (Block n 'Open 'Open -> Block n e x)
    -> Block n 'Open 'Open -> Block n e x
    forall a b. (a -> b) -> a -> b
    $! (Block n 'Open 'Open
    b1 Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e 'Open -> Block n 'Open x -> Block n e x
    `cat` Block n 'Open x
    Block n 'Open 'Open
    y)
                       BSnoc{}      -> n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    BlockCO n 'Closed 'Open
    l (Block n 'Open 'Open -> Block n e x)
    -> Block n 'Open 'Open -> Block n e x
    forall a b. (a -> b) -> a -> b
    $! (Block n 'Open 'Open
    b1 Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e 'Open -> Block n 'Open x -> Block n e x
    `cat` Block n 'Open x
    Block n 'Open 'Open
    y)
                       BCons{}      -> n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    BlockCO n 'Closed 'Open
    l (Block n 'Open 'Open -> Block n e x)
    -> Block n 'Open 'Open -> Block n e x
    forall a b. (a -> b) -> a -> b
    $! (Block n 'Open 'Open
    b1 Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e 'Open -> Block n 'Open x -> Block n e x
    `cat` Block n 'Open x
    Block n 'Open 'Open
    y)

      BMiddle n 'Open 'Open
    n -> case Block n 'Open x
    y of
                       BlockOC Block n 'Open 'Open
    b2 n 'Open 'Closed
    n2 -> (Block n 'Open 'Open -> n 'Open 'Closed -> Block n e x
    Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    BlockOC (Block n 'Open 'Open -> n 'Open 'Closed -> Block n e x)
    -> Block n 'Open 'Open -> n 'Open 'Closed -> Block n e x
    forall a b. (a -> b) -> a -> b
    $! (Block n e 'Open
    Block n 'Open 'Open
    x Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e 'Open -> Block n 'Open x -> Block n e x
    `cat` Block n 'Open 'Open
    b2)) n 'Open 'Closed
    n2
                       Block n 'Open x
    BNil          -> Block n e x
    Block n e 'Open
    x
                       BMiddle{}     -> n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCons n 'Open 'Open
    n Block n 'Open x
    Block n 'Open 'Open
    y
                       BCat{}        -> n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCons n 'Open 'Open
    n Block n 'Open x
    Block n 'Open 'Open
    y
                       BSnoc{}       -> n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCons n 'Open 'Open
    n Block n 'Open x
    Block n 'Open 'Open
    y
                       BCons{}       -> n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCons n 'Open 'Open
    n Block n 'Open x
    Block n 'Open 'Open
    y

      BCat{} -> case Block n 'Open x
    y of
                       BlockOC Block n 'Open 'Open
    b3 n 'Open 'Closed
    n2 -> (Block n 'Open 'Open -> n 'Open 'Closed -> Block n e x
    Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    BlockOC (Block n 'Open 'Open -> n 'Open 'Closed -> Block n e x)
    -> Block n 'Open 'Open -> n 'Open 'Closed -> Block n e x
    forall a b. (a -> b) -> a -> b
    $! (Block n e 'Open
    Block n 'Open 'Open
    x Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e 'Open -> Block n 'Open x -> Block n e x
    `cat` Block n 'Open 'Open
    b3)) n 'Open 'Closed
    n2
                       Block n 'Open x
    BNil          -> Block n e x
    Block n e 'Open
    x
                       BMiddle n 'Open 'Open
    n     -> Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    BSnoc Block n e 'Open
    Block n 'Open 'Open
    x n 'Open 'Open
    n
                       BCat{}        -> Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCat Block n e 'Open
    Block n 'Open 'Open
    x Block n 'Open x
    Block n 'Open 'Open
    y
                       BSnoc{}       -> Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCat Block n e 'Open
    Block n 'Open 'Open
    x Block n 'Open x
    Block n 'Open 'Open
    y
                       BCons{}       -> Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCat Block n e 'Open
    Block n 'Open 'Open
    x Block n 'Open x
    Block n 'Open 'Open
    y

      BSnoc{} -> case Block n 'Open x
    y of
                       BlockOC Block n 'Open 'Open
    b2 n 'Open 'Closed
    n2 -> (Block n 'Open 'Open -> n 'Open 'Closed -> Block n e x
    Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    BlockOC (Block n 'Open 'Open -> n 'Open 'Closed -> Block n e x)
    -> Block n 'Open 'Open -> n 'Open 'Closed -> Block n e x
    forall a b. (a -> b) -> a -> b
    $! (Block n e 'Open
    Block n 'Open 'Open
    x Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e 'Open -> Block n 'Open x -> Block n e x
    `cat` Block n 'Open 'Open
    b2)) n 'Open 'Closed
    n2
                       Block n 'Open x
    BNil          -> Block n e x
    Block n e 'Open
    x
                       BMiddle n 'Open 'Open
    n     -> Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    BSnoc Block n e 'Open
    Block n 'Open 'Open
    x n 'Open 'Open
    n
                       BCat{}        -> Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCat Block n e 'Open
    Block n 'Open 'Open
    x Block n 'Open x
    Block n 'Open 'Open
    y
                       BSnoc{}       -> Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCat Block n e 'Open
    Block n 'Open 'Open
    x Block n 'Open x
    Block n 'Open 'Open
    y
                       BCons{}       -> Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCat Block n e 'Open
    Block n 'Open 'Open
    x Block n 'Open x
    Block n 'Open 'Open
    y

      BCons{} -> case Block n 'Open x
    y of
                       BlockOC Block n 'Open 'Open
    b2 n 'Open 'Closed
    n2 -> (Block n 'Open 'Open -> n 'Open 'Closed -> Block n e x
    Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    BlockOC (Block n 'Open 'Open -> n 'Open 'Closed -> Block n e x)
    -> Block n 'Open 'Open -> n 'Open 'Closed -> Block n e x
    forall a b. (a -> b) -> a -> b
    $! (Block n e 'Open
    Block n 'Open 'Open
    x Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (e :: Extensibility) (x :: Extensibility).
    Block n e 'Open -> Block n 'Open x -> Block n e x
    `cat` Block n 'Open 'Open
    b2)) n 'Open 'Closed
    n2
                       Block n 'Open x
    BNil          -> Block n e x
    Block n e 'Open
    x
                       BMiddle n 'Open 'Open
    n     -> Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    BSnoc Block n e 'Open
    Block n 'Open 'Open
    x n 'Open 'Open
    n
                       BCat{}        -> Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCat Block n e 'Open
    Block n 'Open 'Open
    x Block n 'Open x
    Block n 'Open 'Open
    y
                       BSnoc{}       -> Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCat Block n e 'Open
    Block n 'Open 'Open
    x Block n 'Open x
    Block n 'Open 'Open
    y
                       BCons{}       -> Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCat Block n e 'Open
    Block n 'Open 'Open
    x Block n 'Open x
    Block n 'Open 'Open
    y

    -- -----------------------------------------------------------------------------
    -- Mapping

    -- | map a function over the nodes of a 'Block'
    mapBlock :: (forall e x. n e x -> n' e x) -> Block n e x -> Block n' e x
    mapBlock :: forall (n :: Extensibility -> Extensibility -> *)
           (n' :: Extensibility -> Extensibility -> *) (e :: Extensibility)
           (x :: Extensibility).
    (forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n e x -> Block n' e x
    mapBlock forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f (BlockCO n 'Closed 'Open
    n Block n 'Open 'Open
    b  ) = n' 'Closed 'Open -> Block n' 'Open 'Open -> Block n' 'Closed 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    BlockCO (n 'Closed 'Open -> n' 'Closed 'Open
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f n 'Closed 'Open
    n) ((forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n 'Open 'Open -> Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (n' :: Extensibility -> Extensibility -> *) (e :: Extensibility)
           (x :: Extensibility).
    (forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n e x -> Block n' e x
    mapBlock n e x -> n' e x
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f Block n 'Open 'Open
    b)
    mapBlock forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f (BlockOC   Block n 'Open 'Open
    b n 'Open 'Closed
    n) = Block n' 'Open 'Open -> n' 'Open 'Closed -> Block n' 'Open 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    BlockOC       ((forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n 'Open 'Open -> Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (n' :: Extensibility -> Extensibility -> *) (e :: Extensibility)
           (x :: Extensibility).
    (forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n e x -> Block n' e x
    mapBlock n e x -> n' e x
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f Block n 'Open 'Open
    b) (n 'Open 'Closed -> n' 'Open 'Closed
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f n 'Open 'Closed
    n)
    mapBlock forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f (BlockCC n 'Closed 'Open
    n Block n 'Open 'Open
    b n 'Open 'Closed
    m) = n' 'Closed 'Open
    -> Block n' 'Open 'Open
    -> n' 'Open 'Closed
    -> Block n' 'Closed 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open
    -> Block n 'Open 'Open
    -> n 'Open 'Closed
    -> Block n 'Closed 'Closed
    BlockCC (n 'Closed 'Open -> n' 'Closed 'Open
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f n 'Closed 'Open
    n) ((forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n 'Open 'Open -> Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (n' :: Extensibility -> Extensibility -> *) (e :: Extensibility)
           (x :: Extensibility).
    (forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n e x -> Block n' e x
    mapBlock n e x -> n' e x
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f Block n 'Open 'Open
    b) (n 'Open 'Closed -> n' 'Open 'Closed
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f n 'Open 'Closed
    m)
    mapBlock forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    _  Block n e x
    BNil           = Block n' e x
    Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open
    BNil
    mapBlock forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f (BMiddle n 'Open 'Open
    n)     = n' 'Open 'Open -> Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Open 'Open -> Block n 'Open 'Open
    BMiddle (n 'Open 'Open -> n' 'Open 'Open
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f n 'Open 'Open
    n)
    mapBlock forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f (BCat Block n 'Open 'Open
    b1 Block n 'Open 'Open
    b2)    = Block n' 'Open 'Open
    -> Block n' 'Open 'Open -> Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCat    ((forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n 'Open 'Open -> Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (n' :: Extensibility -> Extensibility -> *) (e :: Extensibility)
           (x :: Extensibility).
    (forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n e x -> Block n' e x
    mapBlock n e x -> n' e x
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f Block n 'Open 'Open
    b1) ((forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n 'Open 'Open -> Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (n' :: Extensibility -> Extensibility -> *) (e :: Extensibility)
           (x :: Extensibility).
    (forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n e x -> Block n' e x
    mapBlock n e x -> n' e x
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f Block n 'Open 'Open
    b2)
    mapBlock forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f (BSnoc Block n 'Open 'Open
    b n 'Open 'Open
    n)     = Block n' 'Open 'Open -> n' 'Open 'Open -> Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    BSnoc   ((forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n 'Open 'Open -> Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (n' :: Extensibility -> Extensibility -> *) (e :: Extensibility)
           (x :: Extensibility).
    (forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n e x -> Block n' e x
    mapBlock n e x -> n' e x
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f Block n 'Open 'Open
    b)  (n 'Open 'Open -> n' 'Open 'Open
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f n 'Open 'Open
    n)
    mapBlock forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f (BCons n 'Open 'Open
    n Block n 'Open 'Open
    b)     = n' 'Open 'Open -> Block n' 'Open 'Open -> Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCons   (n 'Open 'Open -> n' 'Open 'Open
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f n 'Open 'Open
    n)  ((forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n 'Open 'Open -> Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *)
           (n' :: Extensibility -> Extensibility -> *) (e :: Extensibility)
           (x :: Extensibility).
    (forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n e x -> Block n' e x
    mapBlock n e x -> n' e x
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f Block n 'Open 'Open
    b)

    -- | A strict 'mapBlock'
    mapBlock' :: (forall e x. n e x -> n' e x) -> (Block n e x -> Block n' e x)
    mapBlock' :: forall (n :: Extensibility -> Extensibility -> *)
           (n' :: Extensibility -> Extensibility -> *) (e :: Extensibility)
           (x :: Extensibility).
    (forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x)
    -> Block n e x -> Block n' e x
    mapBlock' forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f = (n 'Closed 'Open -> n' 'Closed 'Open,
     n 'Open 'Open -> n' 'Open 'Open,
     n 'Open 'Closed -> n' 'Open 'Closed)
    -> Block n e x -> Block n' e x
    forall (n :: Extensibility -> Extensibility -> *)
           (n' :: Extensibility -> Extensibility -> *) (e :: Extensibility)
           (x :: Extensibility).
    (n 'Closed 'Open -> n' 'Closed 'Open,
     n 'Open 'Open -> n' 'Open 'Open,
     n 'Open 'Closed -> n' 'Open 'Closed)
    -> Block n e x -> Block n' e x
    mapBlock3' (n 'Closed 'Open -> n' 'Closed 'Open
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f, n 'Open 'Open -> n' 'Open 'Open
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f, n 'Open 'Closed -> n' 'Open 'Closed
    forall (e :: Extensibility) (x :: Extensibility). n e x -> n' e x
    f)

    -- | map over a block, with different functions to apply to first nodes,
    -- middle nodes and last nodes respectively.  The map is strict.
    --
    mapBlock3' :: forall n n' e x .
                 ( n C O -> n' C O
                 , n O O -> n' O O,
                   n O C -> n' O C)
              -> Block n e x -> Block n' e x
    mapBlock3' :: forall (n :: Extensibility -> Extensibility -> *)
           (n' :: Extensibility -> Extensibility -> *) (e :: Extensibility)
           (x :: Extensibility).
    (n 'Closed 'Open -> n' 'Closed 'Open,
     n 'Open 'Open -> n' 'Open 'Open,
     n 'Open 'Closed -> n' 'Open 'Closed)
    -> Block n e x -> Block n' e x
    mapBlock3' (n 'Closed 'Open -> n' 'Closed 'Open
    f, n 'Open 'Open -> n' 'Open 'Open
    m, n 'Open 'Closed -> n' 'Open 'Closed
    l) Block n e x
    b = Block n e x -> Block n' e x
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> Block n' e x
    go Block n e x
    b
      where go :: forall e x . Block n e x -> Block n' e x
            go :: forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> Block n' e x
    go (BlockOC Block n 'Open 'Open
    b n 'Open 'Closed
    y)   = (Block n' 'Open 'Open -> n' 'Open 'Closed -> Block n' e x
    Block n' 'Open 'Open -> n' 'Open 'Closed -> Block n' 'Open 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Closed -> Block n 'Open 'Closed
    BlockOC (Block n' 'Open 'Open -> n' 'Open 'Closed -> Block n' e x)
    -> Block n' 'Open 'Open -> n' 'Open 'Closed -> Block n' e x
    forall a b. (a -> b) -> a -> b
    $! Block n 'Open 'Open -> Block n' 'Open 'Open
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> Block n' e x
    go Block n 'Open 'Open
    b) (n' 'Open 'Closed -> Block n' e x)
    -> n' 'Open 'Closed -> Block n' e x
    forall a b. (a -> b) -> a -> b
    $! n 'Open 'Closed -> n' 'Open 'Closed
    l n 'Open 'Closed
    y
            go (BlockCO n 'Closed 'Open
    x Block n 'Open 'Open
    b)   = (n' 'Closed 'Open -> Block n' 'Open 'Open -> Block n' e x
    n' 'Closed 'Open -> Block n' 'Open 'Open -> Block n' 'Closed 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open -> Block n 'Open 'Open -> Block n 'Closed 'Open
    BlockCO (n' 'Closed 'Open -> Block n' 'Open 'Open -> Block n' e x)
    -> n' 'Closed 'Open -> Block n' 'Open 'Open -> Block n' e x
    forall a b. (a -> b) -> a -> b
    $! n 'Closed 'Open -> n' 'Closed 'Open
    f n 'Closed 'Open
    x) (Block n' 'Open 'Open -> Block n' e x)
    -> Block n' 'Open 'Open -> Block n' e x
    forall a b. (a -> b) -> a -> b
    $! (Block n 'Open 'Open -> Block n' 'Open 'Open
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> Block n' e x
    go Block n 'Open 'Open
    b)
            go (BlockCC n 'Closed 'Open
    x Block n 'Open 'Open
    b n 'Open 'Closed
    y) = ((n' 'Closed 'Open
    -> Block n' 'Open 'Open -> n' 'Open 'Closed -> Block n' e x
    n' 'Closed 'Open
    -> Block n' 'Open 'Open
    -> n' 'Open 'Closed
    -> Block n' 'Closed 'Closed
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Closed 'Open
    -> Block n 'Open 'Open
    -> n 'Open 'Closed
    -> Block n 'Closed 'Closed
    BlockCC (n' 'Closed 'Open
     -> Block n' 'Open 'Open -> n' 'Open 'Closed -> Block n' e x)
    -> n' 'Closed 'Open
    -> Block n' 'Open 'Open
    -> n' 'Open 'Closed
    -> Block n' e x
    forall a b. (a -> b) -> a -> b
    $! n 'Closed 'Open -> n' 'Closed 'Open
    f n 'Closed 'Open
    x) (Block n' 'Open 'Open -> n' 'Open 'Closed -> Block n' e x)
    -> Block n' 'Open 'Open -> n' 'Open 'Closed -> Block n' e x
    forall a b. (a -> b) -> a -> b
    $! Block n 'Open 'Open -> Block n' 'Open 'Open
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> Block n' e x
    go Block n 'Open 'Open
    b) (n' 'Open 'Closed -> Block n' e x)
    -> n' 'Open 'Closed -> Block n' e x
    forall a b. (a -> b) -> a -> b
    $! (n 'Open 'Closed -> n' 'Open 'Closed
    l n 'Open 'Closed
    y)
            go Block n e x
    BNil            = Block n' e x
    Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open
    BNil
            go (BMiddle n 'Open 'Open
    n)     = n' 'Open 'Open -> Block n' e x
    n' 'Open 'Open -> Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Open 'Open -> Block n 'Open 'Open
    BMiddle (n' 'Open 'Open -> Block n' e x) -> n' 'Open 'Open -> Block n' e x
    forall a b. (a -> b) -> a -> b
    $! n 'Open 'Open -> n' 'Open 'Open
    m n 'Open 'Open
    n
            go (BCat Block n 'Open 'Open
    x Block n 'Open 'Open
    y)      = (Block n' 'Open 'Open -> Block n' 'Open 'Open -> Block n' e x
    Block n' 'Open 'Open
    -> Block n' 'Open 'Open -> Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCat (Block n' 'Open 'Open -> Block n' 'Open 'Open -> Block n' e x)
    -> Block n' 'Open 'Open -> Block n' 'Open 'Open -> Block n' e x
    forall a b. (a -> b) -> a -> b
    $! Block n 'Open 'Open -> Block n' 'Open 'Open
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> Block n' e x
    go Block n 'Open 'Open
    x) (Block n' 'Open 'Open -> Block n' e x)
    -> Block n' 'Open 'Open -> Block n' e x
    forall a b. (a -> b) -> a -> b
    $! (Block n 'Open 'Open -> Block n' 'Open 'Open
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> Block n' e x
    go Block n 'Open 'Open
    y)
            go (BSnoc Block n 'Open 'Open
    x n 'Open 'Open
    n)     = (Block n' 'Open 'Open -> n' 'Open 'Open -> Block n' e x
    Block n' 'Open 'Open -> n' 'Open 'Open -> Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    Block n 'Open 'Open -> n 'Open 'Open -> Block n 'Open 'Open
    BSnoc (Block n' 'Open 'Open -> n' 'Open 'Open -> Block n' e x)
    -> Block n' 'Open 'Open -> n' 'Open 'Open -> Block n' e x
    forall a b. (a -> b) -> a -> b
    $! Block n 'Open 'Open -> Block n' 'Open 'Open
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> Block n' e x
    go Block n 'Open 'Open
    x) (n' 'Open 'Open -> Block n' e x) -> n' 'Open 'Open -> Block n' e x
    forall a b. (a -> b) -> a -> b
    $! (n 'Open 'Open -> n' 'Open 'Open
    m n 'Open 'Open
    n)
            go (BCons n 'Open 'Open
    n Block n 'Open 'Open
    x)     = (n' 'Open 'Open -> Block n' 'Open 'Open -> Block n' e x
    n' 'Open 'Open -> Block n' 'Open 'Open -> Block n' 'Open 'Open
    forall (n :: Extensibility -> Extensibility -> *).
    n 'Open 'Open -> Block n 'Open 'Open -> Block n 'Open 'Open
    BCons (n' 'Open 'Open -> Block n' 'Open 'Open -> Block n' e x)
    -> n' 'Open 'Open -> Block n' 'Open 'Open -> Block n' e x
    forall a b. (a -> b) -> a -> b
    $! n 'Open 'Open -> n' 'Open 'Open
    m n 'Open 'Open
    n) (Block n' 'Open 'Open -> Block n' e x)
    -> Block n' 'Open 'Open -> Block n' e x
    forall a b. (a -> b) -> a -> b
    $! (Block n 'Open 'Open -> Block n' 'Open 'Open
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> Block n' e x
    go Block n 'Open 'Open
    x)

    -- -----------------------------------------------------------------------------
    -- Folding

    -- | Fold a function over every node in a block, forward or backward.
    -- The fold function must be polymorphic in the shape of the nodes.
    foldBlockNodesF3 :: forall n a b c .
                       ( n C O       -> a -> b
                       , n O O       -> b -> b
                       , n O C       -> b -> c)
                     -> (forall e x . Block n e x -> IndexedCO e a b -> IndexedCO x c b)
    foldBlockNodesF  :: forall n a .
                        (forall e x . n e x       -> a -> a)
                     -> (forall e x . Block n e x -> IndexedCO e a a -> IndexedCO x a a)
    foldBlockNodesB3 :: forall n a b c .
                       ( n C O       -> b -> c
                       , n O O       -> b -> b
                       , n O C       -> a -> b)
                     -> (forall e x . Block n e x -> IndexedCO x a b -> IndexedCO e c b)
    foldBlockNodesB  :: forall n a .
                        (forall e x . n e x       -> a -> a)
                     -> (forall e x . Block n e x -> IndexedCO x a a -> IndexedCO e a a)

    foldBlockNodesF3 :: forall (n :: Extensibility -> Extensibility -> *) a b c.
    (n 'Closed 'Open -> a -> b, n 'Open 'Open -> b -> b,
     n 'Open 'Closed -> b -> c)
    -> forall (e :: Extensibility) (x :: Extensibility).
       Block n e x -> IndexedCO e a b -> IndexedCO x c b
    foldBlockNodesF3 (n 'Closed 'Open -> a -> b
    ff, n 'Open 'Open -> b -> b
    fm, n 'Open 'Closed -> b -> c
    fl) = Block n e x -> IndexedCO e a b -> IndexedCO x c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO e a b -> IndexedCO x c b
    block
      where block :: forall e x . Block n e x -> IndexedCO e a b -> IndexedCO x c b
            block :: forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO e a b -> IndexedCO x c b
    block (BlockCO n 'Closed 'Open
    f Block n 'Open 'Open
    b  )   = n 'Closed 'Open -> a -> b
    ff n 'Closed 'Open
    f (a -> b) -> (b -> b) -> a -> b
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    `cat` Block n 'Open 'Open -> IndexedCO 'Open a b -> IndexedCO 'Open c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO e a b -> IndexedCO x c b
    block Block n 'Open 'Open
    b
            block (BlockCC n 'Closed 'Open
    f Block n 'Open 'Open
    b n 'Open 'Closed
    l)   = n 'Closed 'Open -> a -> b
    ff n 'Closed 'Open
    f (a -> b) -> (b -> b) -> a -> b
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    `cat` Block n 'Open 'Open -> IndexedCO 'Open a b -> IndexedCO 'Open c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO e a b -> IndexedCO x c b
    block Block n 'Open 'Open
    b (a -> b) -> (b -> c) -> a -> c
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    `cat` n 'Open 'Closed -> b -> c
    fl n 'Open 'Closed
    l
            block (BlockOC   Block n 'Open 'Open
    b n 'Open 'Closed
    l)   =            Block n 'Open 'Open -> IndexedCO 'Open a b -> IndexedCO 'Open c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO e a b -> IndexedCO x c b
    block Block n 'Open 'Open
    b (b -> b) -> (b -> c) -> b -> c
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    `cat` n 'Open 'Closed -> b -> c
    fl n 'Open 'Closed
    l
            block Block n e x
    BNil              = b -> b
    IndexedCO e a b -> IndexedCO x c b
    forall a. a -> a
    id
            block (BMiddle n 'Open 'Open
    node)    = n 'Open 'Open -> b -> b
    fm n 'Open 'Open
    node
            block (Block n 'Open 'Open
    b1 `BCat`    Block n 'Open 'Open
    b2) = Block n 'Open 'Open -> IndexedCO 'Open a b -> IndexedCO 'Open c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO e a b -> IndexedCO x c b
    block Block n 'Open 'Open
    b1 (b -> b) -> (b -> b) -> b -> b
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    `cat` Block n 'Open 'Open -> IndexedCO 'Open a b -> IndexedCO 'Open c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO e a b -> IndexedCO x c b
    block Block n 'Open 'Open
    b2
            block (Block n 'Open 'Open
    b1 `BSnoc` n 'Open 'Open
    n)    = Block n 'Open 'Open -> IndexedCO 'Open a b -> IndexedCO 'Open c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO e a b -> IndexedCO x c b
    block Block n 'Open 'Open
    b1 (b -> b) -> (b -> b) -> b -> b
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    `cat` n 'Open 'Open -> b -> b
    fm n 'Open 'Open
    n
            block (n 'Open 'Open
    n `BCons` Block n 'Open 'Open
    b2)    = n 'Open 'Open -> b -> b
    fm n 'Open 'Open
    n (b -> b) -> (b -> b) -> b -> b
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    `cat` Block n 'Open 'Open -> IndexedCO 'Open a b -> IndexedCO 'Open c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO e a b -> IndexedCO x c b
    block Block n 'Open 'Open
    b2
            cat :: forall a b c. (a -> b) -> (b -> c) -> a -> c
            cat :: forall a b c. (a -> b) -> (b -> c) -> a -> c
    cat a -> b
    f b -> c
    f' = b -> c
    f' (b -> c) -> (a -> b) -> a -> c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> b
    f

    foldBlockNodesF :: forall (n :: Extensibility -> Extensibility -> *) a.
    (forall (e :: Extensibility) (x :: Extensibility). n e x -> a -> a)
    -> forall (e :: Extensibility) (x :: Extensibility).
       Block n e x -> IndexedCO e a a -> IndexedCO x a a
    foldBlockNodesF forall (e :: Extensibility) (x :: Extensibility). n e x -> a -> a
    f = (n 'Closed 'Open -> a -> a, n 'Open 'Open -> a -> a,
     n 'Open 'Closed -> a -> a)
    -> forall (e :: Extensibility) (x :: Extensibility).
       Block n e x -> IndexedCO e a a -> IndexedCO x a a
    forall (n :: Extensibility -> Extensibility -> *) a b c.
    (n 'Closed 'Open -> a -> b, n 'Open 'Open -> b -> b,
     n 'Open 'Closed -> b -> c)
    -> forall (e :: Extensibility) (x :: Extensibility).
       Block n e x -> IndexedCO e a b -> IndexedCO x c b
    foldBlockNodesF3 (n 'Closed 'Open -> a -> a
    forall (e :: Extensibility) (x :: Extensibility). n e x -> a -> a
    f, n 'Open 'Open -> a -> a
    forall (e :: Extensibility) (x :: Extensibility). n e x -> a -> a
    f, n 'Open 'Closed -> a -> a
    forall (e :: Extensibility) (x :: Extensibility). n e x -> a -> a
    f)

    foldBlockNodesB3 :: forall (n :: Extensibility -> Extensibility -> *) a b c.
    (n 'Closed 'Open -> b -> c, n 'Open 'Open -> b -> b,
     n 'Open 'Closed -> a -> b)
    -> forall (e :: Extensibility) (x :: Extensibility).
       Block n e x -> IndexedCO x a b -> IndexedCO e c b
    foldBlockNodesB3 (n 'Closed 'Open -> b -> c
    ff, n 'Open 'Open -> b -> b
    fm, n 'Open 'Closed -> a -> b
    fl) = Block n e x -> IndexedCO x a b -> IndexedCO e c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO x a b -> IndexedCO e c b
    block
      where block :: forall e x . Block n e x -> IndexedCO x a b -> IndexedCO e c b
            block :: forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO x a b -> IndexedCO e c b
    block (BlockCO n 'Closed 'Open
    f Block n 'Open 'Open
    b  )   = n 'Closed 'Open -> b -> c
    ff n 'Closed 'Open
    f (b -> c) -> (b -> b) -> b -> c
    forall a b c. (b -> c) -> (a -> b) -> a -> c
    `cat` Block n 'Open 'Open -> IndexedCO 'Open a b -> IndexedCO 'Open c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO x a b -> IndexedCO e c b
    block Block n 'Open 'Open
    b
            block (BlockCC n 'Closed 'Open
    f Block n 'Open 'Open
    b n 'Open 'Closed
    l)   = n 'Closed 'Open -> b -> c
    ff n 'Closed 'Open
    f (b -> c) -> (b -> b) -> b -> c
    forall a b c. (b -> c) -> (a -> b) -> a -> c
    `cat` Block n 'Open 'Open -> IndexedCO 'Open a b -> IndexedCO 'Open c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO x a b -> IndexedCO e c b
    block Block n 'Open 'Open
    b (b -> c) -> (a -> b) -> a -> c
    forall a b c. (b -> c) -> (a -> b) -> a -> c
    `cat` n 'Open 'Closed -> a -> b
    fl n 'Open 'Closed
    l
            block (BlockOC   Block n 'Open 'Open
    b n 'Open 'Closed
    l)   =            Block n 'Open 'Open -> IndexedCO 'Open a b -> IndexedCO 'Open c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO x a b -> IndexedCO e c b
    block Block n 'Open 'Open
    b (b -> b) -> (a -> b) -> a -> b
    forall a b c. (b -> c) -> (a -> b) -> a -> c
    `cat` n 'Open 'Closed -> a -> b
    fl n 'Open 'Closed
    l
            block Block n e x
    BNil              = b -> b
    IndexedCO x a b -> IndexedCO e c b
    forall a. a -> a
    id
            block (BMiddle n 'Open 'Open
    node)    = n 'Open 'Open -> b -> b
    fm n 'Open 'Open
    node
            block (Block n 'Open 'Open
    b1 `BCat`    Block n 'Open 'Open
    b2) = Block n 'Open 'Open -> IndexedCO 'Open a b -> IndexedCO 'Open c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO x a b -> IndexedCO e c b
    block Block n 'Open 'Open
    b1 (b -> b) -> (b -> b) -> b -> b
    forall a b c. (b -> c) -> (a -> b) -> a -> c
    `cat` Block n 'Open 'Open -> IndexedCO 'Open a b -> IndexedCO 'Open c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO x a b -> IndexedCO e c b
    block Block n 'Open 'Open
    b2
            block (Block n 'Open 'Open
    b1 `BSnoc` n 'Open 'Open
    n)    = Block n 'Open 'Open -> IndexedCO 'Open a b -> IndexedCO 'Open c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO x a b -> IndexedCO e c b
    block Block n 'Open 'Open
    b1 (b -> b) -> (b -> b) -> b -> b
    forall a b c. (b -> c) -> (a -> b) -> a -> c
    `cat` n 'Open 'Open -> b -> b
    fm n 'Open 'Open
    n
            block (n 'Open 'Open
    n `BCons` Block n 'Open 'Open
    b2)    = n 'Open 'Open -> b -> b
    fm n 'Open 'Open
    n (b -> b) -> (b -> b) -> b -> b
    forall a b c. (b -> c) -> (a -> b) -> a -> c
    `cat` Block n 'Open 'Open -> IndexedCO 'Open a b -> IndexedCO 'Open c b
    forall (e :: Extensibility) (x :: Extensibility).
    Block n e x -> IndexedCO x a b -> IndexedCO e c b
    block Block n 'Open 'Open
    b2
            cat :: forall a b c. (b -> c) -> (a -> b) -> a -> c
            cat :: forall a b c. (b -> c) -> (a -> b) -> a -> c
    cat b -> c
    f a -> b
    f' = b -> c
    f (b -> c) -> (a -> b) -> a -> c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> b
    f'

    foldBlockNodesB :: forall (n :: Extensibility -> Extensibility -> *) a.
    (forall (e :: Extensibility) (x :: Extensibility). n e x -> a -> a)
    -> forall (e :: Extensibility) (x :: Extensibility).
       Block n e x -> IndexedCO x a a -> IndexedCO e a a
    foldBlockNodesB forall (e :: Extensibility) (x :: Extensibility). n e x -> a -> a
    f = (n 'Closed 'Open -> a -> a, n 'Open 'Open -> a -> a,
     n 'Open 'Closed -> a -> a)
    -> forall (e :: Extensibility) (x :: Extensibility).
       Block n e x -> IndexedCO x a a -> IndexedCO e a a
    forall (n :: Extensibility -> Extensibility -> *) a b c.
    (n 'Closed 'Open -> b -> c, n 'Open 'Open -> b -> b,
     n 'Open 'Closed -> a -> b)
    -> forall (e :: Extensibility) (x :: Extensibility).
       Block n e x -> IndexedCO x a b -> IndexedCO e c b
    foldBlockNodesB3 (n 'Closed 'Open -> a -> a
    forall (e :: Extensibility) (x :: Extensibility). n e x -> a -> a
    f, n 'Open 'Open -> a -> a
    forall (e :: Extensibility) (x :: Extensibility). n e x -> a -> a
    f, n 'Open 'Closed -> a -> a
    forall (e :: Extensibility) (x :: Extensibility). n e x -> a -> a
    f)