    {-|
      Copyright   :  (C) 2019, Myrtle Software Ltd.
                         2018, @blaxill
                         2018, QBayLogic B.V.
      License     :  BSD2 (see the file LICENSE)
      Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com>
    -}
    {-# LANGUAGE CPP #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE NoImplicitPrelude #-}
    {-# LANGUAGE PolyKinds #-}
    {-# LANGUAGE TypeFamilyDependencies #-}

    module Clash.Signal.Delayed.Bundle (
        Bundle(..)
      -- ** Tools to emulate pre Clash 1.0 @Bundle ()@ instance
      , B.EmptyTuple(..)
      , TaggedEmptyTuple(..)
      ) where

    #if !MIN_VERSION_base(4,18,0)
    import           Control.Applicative           (liftA2)
    #endif
    import           GHC.TypeLits                  (KnownNat)
    import           Prelude                       hiding (head, map, tail)

    import           Clash.Signal.Internal         (Domain)
    import           Clash.Signal.Delayed (DSignal, toSignal, unsafeFromSignal)
    import qualified Clash.Signal.Bundle           as B

    import           Clash.Sized.BitVector         (Bit, BitVector)
    import           Clash.Sized.Fixed             (Fixed)
    import           Clash.Sized.Index             (Index)
    import           Clash.Sized.RTree             (RTree, lazyT)
    import           Clash.Sized.Signed            (Signed)
    import           Clash.Sized.Unsigned          (Unsigned)
    import           Clash.Sized.Vector            (Vec, lazyV)

    import           GHC.TypeLits                  (Nat)

    -- | Isomorphism between a 'DSignal' of a product type
    -- (e.g. a tuple) and a product type of 'DSignal's.
    --
    -- Instances of 'Bundle' must satisfy the following laws:
    --
    -- @
    -- 'bundle' . 'unbundle' = 'id'
    -- 'unbundle' . 'bundle' = 'id'
    -- @
    --
    -- By default, 'bundle' and 'unbundle', are defined as the identity, that is,
    -- writing:
    --
    -- @
    -- data D = A | B
    --
    -- instance Bundle D
    -- @
    --
    -- is the same as:
    --
    -- @
    -- data D = A | B
    --
    -- instance Bundle D where
    --   type 'Unbundled' dom delay D = 'DSignal' dom delay D
    --   'bundle'   s = s
    --   'unbundle' s = s
    -- @
    --
    class Bundle a where
      type Unbundled (dom :: Domain) (d :: Nat) a = res | res -> dom d a
      type Unbundled dom d a = DSignal dom d a

      -- | Example:
      --
      -- @
      -- __bundle__ :: ('DSignal' dom d a, 'DSignal' dom d b) -> 'DSignal' dom d (a,b)
      -- @
      --
      -- However:
      --
      -- @
      -- __bundle__ :: 'DSignal' dom 'Clash.Sized.BitVector.Bit' -> 'DSignal' dom 'Clash.Sized.BitVector.Bit'
      -- @
      bundle :: Unbundled dom d a -> DSignal dom d a
      {-# INLINE bundle #-}
      default bundle :: (DSignal dom d a ~ Unbundled dom d a)
                     => Unbundled dom d a -> DSignal dom d a
      bundle Unbundled dom d a
    s = DSignal dom d a
    Unbundled dom d a
    s
      -- | Example:
      --
      -- @
      -- __unbundle__ :: 'DSignal' dom d (a,b) -> ('DSignal' dom d a, 'DSignal' dom d b)
      -- @
      --
      -- However:
      --
      -- @
      -- __unbundle__ :: 'DSignal' dom 'Clash.Sized.BitVector.Bit' -> 'DSignal' dom 'Clash.Sized.BitVector.Bit'
      -- @
      unbundle :: DSignal dom d a -> Unbundled dom d a
      {-# INLINE unbundle #-}
      default unbundle :: (Unbundled dom d a ~ DSignal dom d a)
                       => DSignal dom d a -> Unbundled dom d a
      unbundle DSignal dom d a
    s = DSignal dom d a
    Unbundled dom d a
    s

    instance Bundle ()
    instance Bundle Bool
    instance Bundle Integer
    instance Bundle Int
    instance Bundle Float
    instance Bundle Double
    instance Bundle (Maybe a)
    instance Bundle (Either a b)

    instance Bundle Bit
    instance Bundle (BitVector n)
    instance Bundle (Index n)
    instance Bundle (Fixed rep int frac)
    instance Bundle (Signed n)
    instance Bundle (Unsigned n)

    instance Bundle (a,b) where
      type Unbundled t delay (a,b) = (DSignal t delay a, DSignal t delay b)

      bundle :: forall (dom :: Domain) (d :: Nat).
    Unbundled dom d (a, b) -> DSignal dom d (a, b)
    bundle       = (DSignal dom d a -> DSignal dom d b -> DSignal dom d (a, b))
    -> (DSignal dom d a, DSignal dom d b) -> DSignal dom d (a, b)
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry ((a -> b -> (a, b))
    -> DSignal dom d a -> DSignal dom d b -> DSignal dom d (a, b)
    forall a b c.
    (a -> b -> c)
    -> DSignal dom d a -> DSignal dom d b -> DSignal dom d c
    forall (f :: Type -> Type) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 (,))
      unbundle :: forall (dom :: Domain) (d :: Nat).
    DSignal dom d (a, b) -> Unbundled dom d (a, b)
    unbundle DSignal dom d (a, b)
    tup = (((a, b) -> a) -> DSignal dom d (a, b) -> DSignal dom d a
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (a, b) -> a
    forall a b. (a, b) -> a
    fst DSignal dom d (a, b)
    tup, ((a, b) -> b) -> DSignal dom d (a, b) -> DSignal dom d b
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (a, b) -> b
    forall a b. (a, b) -> b
    snd DSignal dom d (a, b)
    tup)

    instance Bundle (a,b,c) where
      type Unbundled t delay (a,b,c) =
        ( DSignal t delay a, DSignal t delay b, DSignal t delay c)

      bundle :: forall (dom :: Domain) (d :: Nat).
    Unbundled dom d (a, b, c) -> DSignal dom d (a, b, c)
    bundle   (DSignal dom d a
    a,DSignal dom d b
    b,DSignal dom d c
    c) = (,,) (a -> b -> c -> (a, b, c))
    -> DSignal dom d a -> DSignal dom d (b -> c -> (a, b, c))
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    <$> DSignal dom d a
    a DSignal dom d (b -> c -> (a, b, c))
    -> DSignal dom d b -> DSignal dom d (c -> (a, b, c))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d b
    b DSignal dom d (c -> (a, b, c))
    -> DSignal dom d c -> DSignal dom d (a, b, c)
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d c
    c
      unbundle :: forall (dom :: Domain) (d :: Nat).
    DSignal dom d (a, b, c) -> Unbundled dom d (a, b, c)
    unbundle DSignal dom d (a, b, c)
    tup     = (((a, b, c) -> a) -> DSignal dom d (a, b, c) -> DSignal dom d a
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    x,b
    _,c
    _) -> a
    x) DSignal dom d (a, b, c)
    tup
                          ,((a, b, c) -> b) -> DSignal dom d (a, b, c) -> DSignal dom d b
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    x,c
    _) -> b
    x) DSignal dom d (a, b, c)
    tup
                          ,((a, b, c) -> c) -> DSignal dom d (a, b, c) -> DSignal dom d c
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    x) -> c
    x) DSignal dom d (a, b, c)
    tup
                          )
    instance Bundle (a,b,c,d) where
      type Unbundled t delay (a,b,c,d) =
        ( DSignal t delay a, DSignal t delay b, DSignal t delay c, DSignal t delay d)

      bundle :: forall (dom :: Domain) (d :: Nat).
    Unbundled dom d (a, b, c, d) -> DSignal dom d (a, b, c, d)
    bundle   (DSignal dom d a
    a,DSignal dom d b
    b,DSignal dom d c
    c,DSignal dom d d
    d) = (,,,) (a -> b -> c -> d -> (a, b, c, d))
    -> DSignal dom d a -> DSignal dom d (b -> c -> d -> (a, b, c, d))
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    <$> DSignal dom d a
    a DSignal dom d (b -> c -> d -> (a, b, c, d))
    -> DSignal dom d b -> DSignal dom d (c -> d -> (a, b, c, d))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d b
    b DSignal dom d (c -> d -> (a, b, c, d))
    -> DSignal dom d c -> DSignal dom d (d -> (a, b, c, d))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d c
    c DSignal dom d (d -> (a, b, c, d))
    -> DSignal dom d d -> DSignal dom d (a, b, c, d)
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d d
    d
      unbundle :: forall (dom :: Domain) (d :: Nat).
    DSignal dom d (a, b, c, d) -> Unbundled dom d (a, b, c, d)
    unbundle DSignal dom d (a, b, c, d)
    tup     = (((a, b, c, d) -> a)
    -> DSignal dom d (a, b, c, d) -> DSignal dom d a
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    x,b
    _,c
    _,d
    _) -> a
    x) DSignal dom d (a, b, c, d)
    tup
                          ,((a, b, c, d) -> b)
    -> DSignal dom d (a, b, c, d) -> DSignal dom d b
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    x,c
    _,d
    _) -> b
    x) DSignal dom d (a, b, c, d)
    tup
                          ,((a, b, c, d) -> c)
    -> DSignal dom d (a, b, c, d) -> DSignal dom d c
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    x,d
    _) -> c
    x) DSignal dom d (a, b, c, d)
    tup
                          ,((a, b, c, d) -> d)
    -> DSignal dom d (a, b, c, d) -> DSignal dom d d
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    _,d
    x) -> d
    x) DSignal dom d (a, b, c, d)
    tup
                          )

    instance Bundle (a,b,c,d,e) where
      type Unbundled t delay (a,b,c,d,e) =
        ( DSignal t delay a, DSignal t delay b, DSignal t delay c, DSignal t delay d
        , DSignal t delay e)

      bundle :: forall (dom :: Domain) (d :: Nat).
    Unbundled dom d (a, b, c, d, e) -> DSignal dom d (a, b, c, d, e)
    bundle   (DSignal dom d a
    a,DSignal dom d b
    b,DSignal dom d c
    c,DSignal dom d d
    d,DSignal dom d e
    e) = (,,,,) (a -> b -> c -> d -> e -> (a, b, c, d, e))
    -> DSignal dom d a
    -> DSignal dom d (b -> c -> d -> e -> (a, b, c, d, e))
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    <$> DSignal dom d a
    a DSignal dom d (b -> c -> d -> e -> (a, b, c, d, e))
    -> DSignal dom d b
    -> DSignal dom d (c -> d -> e -> (a, b, c, d, e))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d b
    b DSignal dom d (c -> d -> e -> (a, b, c, d, e))
    -> DSignal dom d c -> DSignal dom d (d -> e -> (a, b, c, d, e))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d c
    c DSignal dom d (d -> e -> (a, b, c, d, e))
    -> DSignal dom d d -> DSignal dom d (e -> (a, b, c, d, e))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d d
    d DSignal dom d (e -> (a, b, c, d, e))
    -> DSignal dom d e -> DSignal dom d (a, b, c, d, e)
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d e
    e
      unbundle :: forall (dom :: Domain) (d :: Nat).
    DSignal dom d (a, b, c, d, e) -> Unbundled dom d (a, b, c, d, e)
    unbundle DSignal dom d (a, b, c, d, e)
    tup     = (((a, b, c, d, e) -> a)
    -> DSignal dom d (a, b, c, d, e) -> DSignal dom d a
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    x,b
    _,c
    _,d
    _,e
    _) -> a
    x) DSignal dom d (a, b, c, d, e)
    tup
                          ,((a, b, c, d, e) -> b)
    -> DSignal dom d (a, b, c, d, e) -> DSignal dom d b
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    x,c
    _,d
    _,e
    _) -> b
    x) DSignal dom d (a, b, c, d, e)
    tup
                          ,((a, b, c, d, e) -> c)
    -> DSignal dom d (a, b, c, d, e) -> DSignal dom d c
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    x,d
    _,e
    _) -> c
    x) DSignal dom d (a, b, c, d, e)
    tup
                          ,((a, b, c, d, e) -> d)
    -> DSignal dom d (a, b, c, d, e) -> DSignal dom d d
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    _,d
    x,e
    _) -> d
    x) DSignal dom d (a, b, c, d, e)
    tup
                          ,((a, b, c, d, e) -> e)
    -> DSignal dom d (a, b, c, d, e) -> DSignal dom d e
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    _,d
    _,e
    x) -> e
    x) DSignal dom d (a, b, c, d, e)
    tup
                          )

    instance Bundle (a,b,c,d,e,f) where
      type Unbundled t delay (a,b,c,d,e,f) =
        ( DSignal t delay a, DSignal t delay b, DSignal t delay c, DSignal t delay d
        , DSignal t delay e, DSignal t delay f)

      bundle :: forall (dom :: Domain) (d :: Nat).
    Unbundled dom d (a, b, c, d, e, f)
    -> DSignal dom d (a, b, c, d, e, f)
    bundle   (DSignal dom d a
    a,DSignal dom d b
    b,DSignal dom d c
    c,DSignal dom d d
    d,DSignal dom d e
    e,DSignal dom d f
    f) = (,,,,,) (a -> b -> c -> d -> e -> f -> (a, b, c, d, e, f))
    -> DSignal dom d a
    -> DSignal dom d (b -> c -> d -> e -> f -> (a, b, c, d, e, f))
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    <$> DSignal dom d a
    a DSignal dom d (b -> c -> d -> e -> f -> (a, b, c, d, e, f))
    -> DSignal dom d b
    -> DSignal dom d (c -> d -> e -> f -> (a, b, c, d, e, f))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d b
    b DSignal dom d (c -> d -> e -> f -> (a, b, c, d, e, f))
    -> DSignal dom d c
    -> DSignal dom d (d -> e -> f -> (a, b, c, d, e, f))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d c
    c DSignal dom d (d -> e -> f -> (a, b, c, d, e, f))
    -> DSignal dom d d -> DSignal dom d (e -> f -> (a, b, c, d, e, f))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d d
    d DSignal dom d (e -> f -> (a, b, c, d, e, f))
    -> DSignal dom d e -> DSignal dom d (f -> (a, b, c, d, e, f))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d e
    e DSignal dom d (f -> (a, b, c, d, e, f))
    -> DSignal dom d f -> DSignal dom d (a, b, c, d, e, f)
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d f
    f
      unbundle :: forall (dom :: Domain) (d :: Nat).
    DSignal dom d (a, b, c, d, e, f)
    -> Unbundled dom d (a, b, c, d, e, f)
    unbundle DSignal dom d (a, b, c, d, e, f)
    tup           = (((a, b, c, d, e, f) -> a)
    -> DSignal dom d (a, b, c, d, e, f) -> DSignal dom d a
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    x,b
    _,c
    _,d
    _,e
    _,f
    _) -> a
    x) DSignal dom d (a, b, c, d, e, f)
    tup
                               ,((a, b, c, d, e, f) -> b)
    -> DSignal dom d (a, b, c, d, e, f) -> DSignal dom d b
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    x,c
    _,d
    _,e
    _,f
    _) -> b
    x) DSignal dom d (a, b, c, d, e, f)
    tup
                               ,((a, b, c, d, e, f) -> c)
    -> DSignal dom d (a, b, c, d, e, f) -> DSignal dom d c
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    x,d
    _,e
    _,f
    _) -> c
    x) DSignal dom d (a, b, c, d, e, f)
    tup
                               ,((a, b, c, d, e, f) -> d)
    -> DSignal dom d (a, b, c, d, e, f) -> DSignal dom d d
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    _,d
    x,e
    _,f
    _) -> d
    x) DSignal dom d (a, b, c, d, e, f)
    tup
                               ,((a, b, c, d, e, f) -> e)
    -> DSignal dom d (a, b, c, d, e, f) -> DSignal dom d e
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    _,d
    _,e
    x,f
    _) -> e
    x) DSignal dom d (a, b, c, d, e, f)
    tup
                               ,((a, b, c, d, e, f) -> f)
    -> DSignal dom d (a, b, c, d, e, f) -> DSignal dom d f
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    _,d
    _,e
    _,f
    x) -> f
    x) DSignal dom d (a, b, c, d, e, f)
    tup
                               )

    instance Bundle (a,b,c,d,e,f,g) where
      type Unbundled t delay (a,b,c,d,e,f,g) =
        ( DSignal t delay a, DSignal t delay b, DSignal t delay c, DSignal t delay d
        , DSignal t delay e, DSignal t delay f, DSignal t delay g)

      bundle :: forall (dom :: Domain) (d :: Nat).
    Unbundled dom d (a, b, c, d, e, f, g)
    -> DSignal dom d (a, b, c, d, e, f, g)
    bundle   (DSignal dom d a
    a,DSignal dom d b
    b,DSignal dom d c
    c,DSignal dom d d
    d,DSignal dom d e
    e,DSignal dom d f
    f,DSignal dom d g
    g) = (,,,,,,) (a -> b -> c -> d -> e -> f -> g -> (a, b, c, d, e, f, g))
    -> DSignal dom d a
    -> DSignal
         dom d (b -> c -> d -> e -> f -> g -> (a, b, c, d, e, f, g))
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    <$> DSignal dom d a
    a DSignal dom d (b -> c -> d -> e -> f -> g -> (a, b, c, d, e, f, g))
    -> DSignal dom d b
    -> DSignal dom d (c -> d -> e -> f -> g -> (a, b, c, d, e, f, g))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d b
    b DSignal dom d (c -> d -> e -> f -> g -> (a, b, c, d, e, f, g))
    -> DSignal dom d c
    -> DSignal dom d (d -> e -> f -> g -> (a, b, c, d, e, f, g))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d c
    c DSignal dom d (d -> e -> f -> g -> (a, b, c, d, e, f, g))
    -> DSignal dom d d
    -> DSignal dom d (e -> f -> g -> (a, b, c, d, e, f, g))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d d
    d DSignal dom d (e -> f -> g -> (a, b, c, d, e, f, g))
    -> DSignal dom d e
    -> DSignal dom d (f -> g -> (a, b, c, d, e, f, g))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d e
    e DSignal dom d (f -> g -> (a, b, c, d, e, f, g))
    -> DSignal dom d f -> DSignal dom d (g -> (a, b, c, d, e, f, g))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d f
    f
                                          DSignal dom d (g -> (a, b, c, d, e, f, g))
    -> DSignal dom d g -> DSignal dom d (a, b, c, d, e, f, g)
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d g
    g
      unbundle :: forall (dom :: Domain) (d :: Nat).
    DSignal dom d (a, b, c, d, e, f, g)
    -> Unbundled dom d (a, b, c, d, e, f, g)
    unbundle DSignal dom d (a, b, c, d, e, f, g)
    tup             = (((a, b, c, d, e, f, g) -> a)
    -> DSignal dom d (a, b, c, d, e, f, g) -> DSignal dom d a
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    x,b
    _,c
    _,d
    _,e
    _,f
    _,g
    _) -> a
    x) DSignal dom d (a, b, c, d, e, f, g)
    tup
                                 ,((a, b, c, d, e, f, g) -> b)
    -> DSignal dom d (a, b, c, d, e, f, g) -> DSignal dom d b
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    x,c
    _,d
    _,e
    _,f
    _,g
    _) -> b
    x) DSignal dom d (a, b, c, d, e, f, g)
    tup
                                 ,((a, b, c, d, e, f, g) -> c)
    -> DSignal dom d (a, b, c, d, e, f, g) -> DSignal dom d c
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    x,d
    _,e
    _,f
    _,g
    _) -> c
    x) DSignal dom d (a, b, c, d, e, f, g)
    tup
                                 ,((a, b, c, d, e, f, g) -> d)
    -> DSignal dom d (a, b, c, d, e, f, g) -> DSignal dom d d
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    _,d
    x,e
    _,f
    _,g
    _) -> d
    x) DSignal dom d (a, b, c, d, e, f, g)
    tup
                                 ,((a, b, c, d, e, f, g) -> e)
    -> DSignal dom d (a, b, c, d, e, f, g) -> DSignal dom d e
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    _,d
    _,e
    x,f
    _,g
    _) -> e
    x) DSignal dom d (a, b, c, d, e, f, g)
    tup
                                 ,((a, b, c, d, e, f, g) -> f)
    -> DSignal dom d (a, b, c, d, e, f, g) -> DSignal dom d f
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    _,d
    _,e
    _,f
    x,g
    _) -> f
    x) DSignal dom d (a, b, c, d, e, f, g)
    tup
                                 ,((a, b, c, d, e, f, g) -> g)
    -> DSignal dom d (a, b, c, d, e, f, g) -> DSignal dom d g
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    _,d
    _,e
    _,f
    _,g
    x) -> g
    x) DSignal dom d (a, b, c, d, e, f, g)
    tup
                                 )

    instance Bundle (a,b,c,d,e,f,g,h) where
      type Unbundled t delay (a,b,c,d,e,f,g,h) =
        ( DSignal t delay a, DSignal t delay b, DSignal t delay c, DSignal t delay d
        , DSignal t delay e, DSignal t delay f ,DSignal t delay g, DSignal t delay h)

      bundle :: forall (dom :: Domain) (d :: Nat).
    Unbundled dom d (a, b, c, d, e, f, g, h)
    -> DSignal dom d (a, b, c, d, e, f, g, h)
    bundle   (DSignal dom d a
    a,DSignal dom d b
    b,DSignal dom d c
    c,DSignal dom d d
    d,DSignal dom d e
    e,DSignal dom d f
    f,DSignal dom d g
    g,DSignal dom d h
    h) = (,,,,,,,) (a -> b -> c -> d -> e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
    -> DSignal dom d a
    -> DSignal
         dom d (b -> c -> d -> e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    <$> DSignal dom d a
    a DSignal
      dom d (b -> c -> d -> e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
    -> DSignal dom d b
    -> DSignal
         dom d (c -> d -> e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d b
    b DSignal
      dom d (c -> d -> e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
    -> DSignal dom d c
    -> DSignal
         dom d (d -> e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d c
    c DSignal dom d (d -> e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
    -> DSignal dom d d
    -> DSignal dom d (e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d d
    d DSignal dom d (e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
    -> DSignal dom d e
    -> DSignal dom d (f -> g -> h -> (a, b, c, d, e, f, g, h))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d e
    e DSignal dom d (f -> g -> h -> (a, b, c, d, e, f, g, h))
    -> DSignal dom d f
    -> DSignal dom d (g -> h -> (a, b, c, d, e, f, g, h))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d f
    f
                                             DSignal dom d (g -> h -> (a, b, c, d, e, f, g, h))
    -> DSignal dom d g -> DSignal dom d (h -> (a, b, c, d, e, f, g, h))
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d g
    g DSignal dom d (h -> (a, b, c, d, e, f, g, h))
    -> DSignal dom d h -> DSignal dom d (a, b, c, d, e, f, g, h)
    forall a b.
    DSignal dom d (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> DSignal dom d h
    h
      unbundle :: forall (dom :: Domain) (d :: Nat).
    DSignal dom d (a, b, c, d, e, f, g, h)
    -> Unbundled dom d (a, b, c, d, e, f, g, h)
    unbundle DSignal dom d (a, b, c, d, e, f, g, h)
    tup               = (((a, b, c, d, e, f, g, h) -> a)
    -> DSignal dom d (a, b, c, d, e, f, g, h) -> DSignal dom d a
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    x,b
    _,c
    _,d
    _,e
    _,f
    _,g
    _,h
    _) -> a
    x) DSignal dom d (a, b, c, d, e, f, g, h)
    tup
                                   ,((a, b, c, d, e, f, g, h) -> b)
    -> DSignal dom d (a, b, c, d, e, f, g, h) -> DSignal dom d b
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    x,c
    _,d
    _,e
    _,f
    _,g
    _,h
    _) -> b
    x) DSignal dom d (a, b, c, d, e, f, g, h)
    tup
                                   ,((a, b, c, d, e, f, g, h) -> c)
    -> DSignal dom d (a, b, c, d, e, f, g, h) -> DSignal dom d c
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    x,d
    _,e
    _,f
    _,g
    _,h
    _) -> c
    x) DSignal dom d (a, b, c, d, e, f, g, h)
    tup
                                   ,((a, b, c, d, e, f, g, h) -> d)
    -> DSignal dom d (a, b, c, d, e, f, g, h) -> DSignal dom d d
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    _,d
    x,e
    _,f
    _,g
    _,h
    _) -> d
    x) DSignal dom d (a, b, c, d, e, f, g, h)
    tup
                                   ,((a, b, c, d, e, f, g, h) -> e)
    -> DSignal dom d (a, b, c, d, e, f, g, h) -> DSignal dom d e
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    _,d
    _,e
    x,f
    _,g
    _,h
    _) -> e
    x) DSignal dom d (a, b, c, d, e, f, g, h)
    tup
                                   ,((a, b, c, d, e, f, g, h) -> f)
    -> DSignal dom d (a, b, c, d, e, f, g, h) -> DSignal dom d f
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    _,d
    _,e
    _,f
    x,g
    _,h
    _) -> f
    x) DSignal dom d (a, b, c, d, e, f, g, h)
    tup
                                   ,((a, b, c, d, e, f, g, h) -> g)
    -> DSignal dom d (a, b, c, d, e, f, g, h) -> DSignal dom d g
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    _,d
    _,e
    _,f
    _,g
    x,h
    _) -> g
    x) DSignal dom d (a, b, c, d, e, f, g, h)
    tup
                                   ,((a, b, c, d, e, f, g, h) -> h)
    -> DSignal dom d (a, b, c, d, e, f, g, h) -> DSignal dom d h
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(a
    _,b
    _,c
    _,d
    _,e
    _,f
    _,g
    _,h
    x) -> h
    x) DSignal dom d (a, b, c, d, e, f, g, h)
    tup
                                   )

    instance KnownNat n => Bundle (Vec n a) where
      type Unbundled t d (Vec n a) = Vec n (DSignal t d a)
      bundle :: forall (dom :: Domain) (d :: Nat).
    Unbundled dom d (Vec n a) -> DSignal dom d (Vec n a)
    bundle   = Signal dom (Vec n a) -> DSignal dom d (Vec n a)
    forall (dom :: Domain) a (n :: Nat).
    Signal dom a -> DSignal dom n a
    unsafeFromSignal (Signal dom (Vec n a) -> DSignal dom d (Vec n a))
    -> (Vec n (DSignal dom d a) -> Signal dom (Vec n a))
    -> Vec n (DSignal dom d a)
    -> DSignal dom d (Vec n a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Vec n (Signal dom a) -> Signal dom (Vec n a)
    Unbundled dom (Vec n a) -> Signal dom (Vec n a)
    forall a (dom :: Domain).
    Bundle a =>
    Unbundled dom a -> Signal dom a
    forall (dom :: Domain).
    Unbundled dom (Vec n a) -> Signal dom (Vec n a)
    B.bundle (Vec n (Signal dom a) -> Signal dom (Vec n a))
    -> (Vec n (DSignal dom d a) -> Vec n (Signal dom a))
    -> Vec n (DSignal dom d a)
    -> Signal dom (Vec n a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (DSignal dom d a -> Signal dom a)
    -> Vec n (DSignal dom d a) -> Vec n (Signal dom a)
    forall a b. (a -> b) -> Vec n a -> Vec n b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap DSignal dom d a -> Signal dom a
    forall (dom :: Domain) (delay :: Nat) a.
    DSignal dom delay a -> Signal dom a
    toSignal
      unbundle :: forall (dom :: Domain) (d :: Nat).
    DSignal dom d (Vec n a) -> Unbundled dom d (Vec n a)
    unbundle = DSignal dom d (Vec n a) -> Vec n (DSignal dom d a)
    forall (t :: Type -> Type) (f :: Type -> Type) a.
    (Traversable t, Applicative f) =>
    t (f a) -> f (t a)
    forall (f :: Type -> Type) a.
    Applicative f =>
    DSignal dom d (f a) -> f (DSignal dom d a)
    sequenceA (DSignal dom d (Vec n a) -> Vec n (DSignal dom d a))
    -> (DSignal dom d (Vec n a) -> DSignal dom d (Vec n a))
    -> DSignal dom d (Vec n a)
    -> Vec n (DSignal dom d a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Vec n a -> Vec n a)
    -> DSignal dom d (Vec n a) -> DSignal dom d (Vec n a)
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap Vec n a -> Vec n a
    forall (n :: Nat) a. KnownNat n => Vec n a -> Vec n a
    lazyV

    instance KnownNat d => Bundle (RTree d a) where
      type Unbundled t delay (RTree d a) = RTree d (DSignal t delay a)
      bundle :: forall (dom :: Domain) (d :: Nat).
    Unbundled dom d (RTree d a) -> DSignal dom d (RTree d a)
    bundle   = RTree d (DSignal dom d a) -> DSignal dom d (RTree d a)
    Unbundled dom d (RTree d a) -> DSignal dom d (RTree d a)
    forall (t :: Type -> Type) (f :: Type -> Type) a.
    (Traversable t, Applicative f) =>
    t (f a) -> f (t a)
    forall (f :: Type -> Type) a.
    Applicative f =>
    RTree d (f a) -> f (RTree d a)
    sequenceA
      unbundle :: forall (dom :: Domain) (d :: Nat).
    DSignal dom d (RTree d a) -> Unbundled dom d (RTree d a)
    unbundle = DSignal dom d (RTree d a) -> RTree d (DSignal dom d a)
    forall (t :: Type -> Type) (f :: Type -> Type) a.
    (Traversable t, Applicative f) =>
    t (f a) -> f (t a)
    forall (f :: Type -> Type) a.
    Applicative f =>
    DSignal dom d (f a) -> f (DSignal dom d a)
    sequenceA (DSignal dom d (RTree d a) -> RTree d (DSignal dom d a))
    -> (DSignal dom d (RTree d a) -> DSignal dom d (RTree d a))
    -> DSignal dom d (RTree d a)
    -> RTree d (DSignal dom d a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (RTree d a -> RTree d a)
    -> DSignal dom d (RTree d a) -> DSignal dom d (RTree d a)
    forall a b. (a -> b) -> DSignal dom d a -> DSignal dom d b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap RTree d a -> RTree d a
    forall (d :: Nat) a. KnownNat d => RTree d a -> RTree d a
    lazyT

    -- | Same as 'Clash.Signal.Bundle.TaggedEmptyTuple' in "Clash.Signal.Bundle", but adapted for 'DSignal'.
    data TaggedEmptyTuple (dom :: Domain) (d :: Nat) = TaggedEmptyTuple

    -- | See [commit 94b0bff5](https://github.com/clash-lang/clash-compiler/pull/539/commits/94b0bff5770aa4961e04ddce2515130df3fc7863)
    -- and documentation for 'Clash.Signal.Bundle.TaggedEmptyTuple'.
    instance Bundle B.EmptyTuple where
      type Unbundled dom d B.EmptyTuple = TaggedEmptyTuple dom d

      bundle :: TaggedEmptyTuple dom d -> DSignal dom d B.EmptyTuple
      bundle :: forall (dom :: Domain) (d :: Nat).
    TaggedEmptyTuple dom d -> DSignal dom d EmptyTuple
    bundle TaggedEmptyTuple dom d
    TaggedEmptyTuple = EmptyTuple -> DSignal dom d EmptyTuple
    forall a. a -> DSignal dom d a
    forall (f :: Type -> Type) a. Applicative f => a -> f a
    pure EmptyTuple
    B.EmptyTuple

      unbundle :: DSignal dom d B.EmptyTuple -> TaggedEmptyTuple dom d
      unbundle :: forall (dom :: Domain) (d :: Nat).
    DSignal dom d EmptyTuple -> TaggedEmptyTuple dom d
    unbundle DSignal dom d EmptyTuple
    s = DSignal dom d EmptyTuple
    -> TaggedEmptyTuple dom d -> TaggedEmptyTuple dom d
    forall a b. a -> b -> b
    seq DSignal dom d EmptyTuple
    s TaggedEmptyTuple dom d
    forall (dom :: Domain) (d :: Nat). TaggedEmptyTuple dom d
    TaggedEmptyTuple