    {-|
      Copyright   :  (C) 2019     , Myrtle Software Ltd.
                         2018     , @blaxill
                         2018-2019, QBayLogic B.V.
                         2021     , LUMI GUIDE FIETSDETECTIE B.V.
      License     :  BSD2 (see the file LICENSE)
      Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com>
    -}
    {-# LANGUAGE CPP #-}
    {-# LANGUAGE GADTs #-}
    {-# LANGUAGE RoleAnnotations #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE TypeFamilies #-}

    {-# LANGUAGE Trustworthy #-}

    {-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}
    {-# OPTIONS_HADDOCK show-extensions #-}

    module Clash.Signal.Delayed.Internal
      ( -- * Delay-annotated synchronous signals
        DSignal(..)
      , feedback
      , fromSignal
        -- * List \<-\> DSignal conversion (not synthesizable)
      , dfromList
        -- ** lazy versions
      , dfromList_lazy
        -- * Experimental
      , unsafeFromSignal
      , antiDelay
      , forward
      )
    where

    import Data.Coerce                (coerce)
    import Data.Default.Class         (Default(..))
    import GHC.TypeLits               (Nat, type (+))
    import Language.Haskell.TH.Syntax (Lift)
    import Test.QuickCheck            (Arbitrary, CoArbitrary)

    import Clash.Promoted.Nat         (SNat)
    import Clash.Signal.Internal      (Signal, Domain, fromList, fromList_lazy)
    import Clash.XException           (NFDataX)

    {- $setup
    >>> :set -XDataKinds
    >>> :set -XTypeOperators
    >>> import Clash.Explicit.Prelude
    >>> import qualified Clash.Signal.Delayed.Bundle as DB
    >>> :{
    let mac
          :: forall dom
           . KnownDomain dom
          => Clock dom
          -> Reset dom
          -> Enable dom
          -> DSignal dom 0 Int
          -> DSignal dom 0 Int
          -> DSignal dom 0 Int
        mac clk rst en x y = feedback (mac' x y)
          where
            mac'
              :: DSignal dom 0 Int
              -> DSignal dom 0 Int
              -> DSignal dom 0 Int
              -> (DSignal dom 0 Int, DSignal dom 1 Int)
            mac' a b acc = let acc' = a * b + acc
                           in  (acc, delayedI clk rst en 0 acc')
    :}

    >>> :{
    let numbers
          :: forall dom
           . KnownDomain dom
          => Clock dom
          -> Reset dom
          -> Enable dom
          -> DSignal dom 5 (Int, Int)
        numbers clk rst en = DB.bundle (forward d1 s1, s2)
          where
            s1 :: DSignal dom 4 Int
            s1 = delayed clk rst en (100 :> 10 :> 5 :> 1 :> Nil) (pure 200)
            s2 :: DSignal dom 5 Int
            s2 = fmap (2*) $ delayN d1 0 en clk s1
    :}

    -}

    -- | A synchronized signal with samples of type @a@, synchronized to clock
    -- @clk@, that has accumulated @delay@ amount of samples delay along its path.
    --
    -- DSignal has the <https://downloads.haskell.org/ghc/latest/docs/html/users_guide/exts/roles.html type role>
    --
    -- >>> :i DSignal
    -- type role DSignal nominal nominal representational
    -- ...
    --
    -- as it is safe to coerce the values in the signal, but not safe to coerce the
    -- synthesis domain or delay in the signal.
    type role DSignal nominal nominal representational
    newtype DSignal (dom :: Domain) (delay :: Nat) a =
        DSignal { forall (dom :: Domain) (delay :: Nat) a.
    DSignal dom delay a -> Signal dom a
    toSignal :: Signal dom a
                  -- ^ Strip a 'DSignal' of its delay information.
                }
      deriving ( Int -> DSignal dom delay a -> ShowS
    [DSignal dom delay a] -> ShowS
    DSignal dom delay a -> String
    (Int -> DSignal dom delay a -> ShowS)
    -> (DSignal dom delay a -> String)
    -> ([DSignal dom delay a] -> ShowS)
    -> Show (DSignal dom delay a)
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    forall (dom :: Domain) (delay :: Nat) a.
    Show a =>
    Int -> DSignal dom delay a -> ShowS
    forall (dom :: Domain) (delay :: Nat) a.
    Show a =>
    [DSignal dom delay a] -> ShowS
    forall (dom :: Domain) (delay :: Nat) a.
    Show a =>
    DSignal dom delay a -> String
    $cshowsPrec :: forall (dom :: Domain) (delay :: Nat) a.
    Show a =>
    Int -> DSignal dom delay a -> ShowS
    showsPrec :: Int -> DSignal dom delay a -> ShowS
    $cshow :: forall (dom :: Domain) (delay :: Nat) a.
    Show a =>
    DSignal dom delay a -> String
    show :: DSignal dom delay a -> String
    $cshowList :: forall (dom :: Domain) (delay :: Nat) a.
    Show a =>
    [DSignal dom delay a] -> ShowS
    showList :: [DSignal dom delay a] -> ShowS
    Show, DSignal dom delay a
    DSignal dom delay a -> Default (DSignal dom delay a)
    forall a. a -> Default a
    forall (dom :: Domain) (delay :: Nat) a.
    Default a =>
    DSignal dom delay a
    $cdef :: forall (dom :: Domain) (delay :: Nat) a.
    Default a =>
    DSignal dom delay a
    def :: DSignal dom delay a
    Default, (forall a b.
     (a -> b) -> DSignal dom delay a -> DSignal dom delay b)
    -> (forall a b. a -> DSignal dom delay b -> DSignal dom delay a)
    -> Functor (DSignal dom delay)
    forall a b. a -> DSignal dom delay b -> DSignal dom delay a
    forall a b. (a -> b) -> DSignal dom delay a -> DSignal dom delay b
    forall (dom :: Domain) (delay :: Nat) a b.
    a -> DSignal dom delay b -> DSignal dom delay a
    forall (dom :: Domain) (delay :: Nat) a b.
    (a -> b) -> DSignal dom delay a -> DSignal dom delay b
    forall (f :: Type -> Type).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall (dom :: Domain) (delay :: Nat) a b.
    (a -> b) -> DSignal dom delay a -> DSignal dom delay b
    fmap :: forall a b. (a -> b) -> DSignal dom delay a -> DSignal dom delay b
    $c<$ :: forall (dom :: Domain) (delay :: Nat) a b.
    a -> DSignal dom delay b -> DSignal dom delay a
    <$ :: forall a b. a -> DSignal dom delay b -> DSignal dom delay a
    Functor, Functor (DSignal dom delay)
    Functor (DSignal dom delay) =>
    (forall a. a -> DSignal dom delay a)
    -> (forall a b.
        DSignal dom delay (a -> b)
        -> DSignal dom delay a -> DSignal dom delay b)
    -> (forall a b c.
        (a -> b -> c)
        -> DSignal dom delay a
        -> DSignal dom delay b
        -> DSignal dom delay c)
    -> (forall a b.
        DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay b)
    -> (forall a b.
        DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay a)
    -> Applicative (DSignal dom delay)
    forall a. a -> DSignal dom delay a
    forall a b.
    DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay a
    forall a b.
    DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay b
    forall a b.
    DSignal dom delay (a -> b)
    -> DSignal dom delay a -> DSignal dom delay b
    forall a b c.
    (a -> b -> c)
    -> DSignal dom delay a
    -> DSignal dom delay b
    -> DSignal dom delay c
    forall (dom :: Domain) (delay :: Nat). Functor (DSignal dom delay)
    forall (dom :: Domain) (delay :: Nat) a. a -> DSignal dom delay a
    forall (dom :: Domain) (delay :: Nat) a b.
    DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay a
    forall (dom :: Domain) (delay :: Nat) a b.
    DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay b
    forall (dom :: Domain) (delay :: Nat) a b.
    DSignal dom delay (a -> b)
    -> DSignal dom delay a -> DSignal dom delay b
    forall (dom :: Domain) (delay :: Nat) a b c.
    (a -> b -> c)
    -> DSignal dom delay a
    -> DSignal dom delay b
    -> DSignal dom delay c
    forall (f :: Type -> Type).
    Functor f =>
    (forall a. a -> f a)
    -> (forall a b. f (a -> b) -> f a -> f b)
    -> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
    -> (forall a b. f a -> f b -> f b)
    -> (forall a b. f a -> f b -> f a)
    -> Applicative f
    $cpure :: forall (dom :: Domain) (delay :: Nat) a. a -> DSignal dom delay a
    pure :: forall a. a -> DSignal dom delay a
    $c<*> :: forall (dom :: Domain) (delay :: Nat) a b.
    DSignal dom delay (a -> b)
    -> DSignal dom delay a -> DSignal dom delay b
    <*> :: forall a b.
    DSignal dom delay (a -> b)
    -> DSignal dom delay a -> DSignal dom delay b
    $cliftA2 :: forall (dom :: Domain) (delay :: Nat) a b c.
    (a -> b -> c)
    -> DSignal dom delay a
    -> DSignal dom delay b
    -> DSignal dom delay c
    liftA2 :: forall a b c.
    (a -> b -> c)
    -> DSignal dom delay a
    -> DSignal dom delay b
    -> DSignal dom delay c
    $c*> :: forall (dom :: Domain) (delay :: Nat) a b.
    DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay b
    *> :: forall a b.
    DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay b
    $c<* :: forall (dom :: Domain) (delay :: Nat) a b.
    DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay a
    <* :: forall a b.
    DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay a
    Applicative, Integer -> DSignal dom delay a
    DSignal dom delay a -> DSignal dom delay a
    DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
    (DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a)
    -> (DSignal dom delay a
        -> DSignal dom delay a -> DSignal dom delay a)
    -> (DSignal dom delay a
        -> DSignal dom delay a -> DSignal dom delay a)
    -> (DSignal dom delay a -> DSignal dom delay a)
    -> (DSignal dom delay a -> DSignal dom delay a)
    -> (DSignal dom delay a -> DSignal dom delay a)
    -> (Integer -> DSignal dom delay a)
    -> Num (DSignal dom delay a)
    forall a.
    (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (Integer -> a)
    -> Num a
    forall (dom :: Domain) (delay :: Nat) a.
    Num a =>
    Integer -> DSignal dom delay a
    forall (dom :: Domain) (delay :: Nat) a.
    Num a =>
    DSignal dom delay a -> DSignal dom delay a
    forall (dom :: Domain) (delay :: Nat) a.
    Num a =>
    DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
    $c+ :: forall (dom :: Domain) (delay :: Nat) a.
    Num a =>
    DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
    + :: DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
    $c- :: forall (dom :: Domain) (delay :: Nat) a.
    Num a =>
    DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
    - :: DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
    $c* :: forall (dom :: Domain) (delay :: Nat) a.
    Num a =>
    DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
    * :: DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
    $cnegate :: forall (dom :: Domain) (delay :: Nat) a.
    Num a =>
    DSignal dom delay a -> DSignal dom delay a
    negate :: DSignal dom delay a -> DSignal dom delay a
    $cabs :: forall (dom :: Domain) (delay :: Nat) a.
    Num a =>
    DSignal dom delay a -> DSignal dom delay a
    abs :: DSignal dom delay a -> DSignal dom delay a
    $csignum :: forall (dom :: Domain) (delay :: Nat) a.
    Num a =>
    DSignal dom delay a -> DSignal dom delay a
    signum :: DSignal dom delay a -> DSignal dom delay a
    $cfromInteger :: forall (dom :: Domain) (delay :: Nat) a.
    Num a =>
    Integer -> DSignal dom delay a
    fromInteger :: Integer -> DSignal dom delay a
    Num, Num (DSignal dom delay a)
    Num (DSignal dom delay a) =>
    (DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a)
    -> (DSignal dom delay a -> DSignal dom delay a)
    -> (Rational -> DSignal dom delay a)
    -> Fractional (DSignal dom delay a)
    Rational -> DSignal dom delay a
    DSignal dom delay a -> DSignal dom delay a
    DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
    forall a.
    Num a =>
    (a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
    forall (dom :: Domain) (delay :: Nat) a.
    Fractional a =>
    Num (DSignal dom delay a)
    forall (dom :: Domain) (delay :: Nat) a.
    Fractional a =>
    Rational -> DSignal dom delay a
    forall (dom :: Domain) (delay :: Nat) a.
    Fractional a =>
    DSignal dom delay a -> DSignal dom delay a
    forall (dom :: Domain) (delay :: Nat) a.
    Fractional a =>
    DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
    $c/ :: forall (dom :: Domain) (delay :: Nat) a.
    Fractional a =>
    DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
    / :: DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
    $crecip :: forall (dom :: Domain) (delay :: Nat) a.
    Fractional a =>
    DSignal dom delay a -> DSignal dom delay a
    recip :: DSignal dom delay a -> DSignal dom delay a
    $cfromRational :: forall (dom :: Domain) (delay :: Nat) a.
    Fractional a =>
    Rational -> DSignal dom delay a
    fromRational :: Rational -> DSignal dom delay a
    Fractional
               , (forall m. Monoid m => DSignal dom delay m -> m)
    -> (forall m a. Monoid m => (a -> m) -> DSignal dom delay a -> m)
    -> (forall m a. Monoid m => (a -> m) -> DSignal dom delay a -> m)
    -> (forall a b. (a -> b -> b) -> b -> DSignal dom delay a -> b)
    -> (forall a b. (a -> b -> b) -> b -> DSignal dom delay a -> b)
    -> (forall b a. (b -> a -> b) -> b -> DSignal dom delay a -> b)
    -> (forall b a. (b -> a -> b) -> b -> DSignal dom delay a -> b)
    -> (forall a. (a -> a -> a) -> DSignal dom delay a -> a)
    -> (forall a. (a -> a -> a) -> DSignal dom delay a -> a)
    -> (forall a. DSignal dom delay a -> [a])
    -> (forall a. DSignal dom delay a -> Bool)
    -> (forall a. DSignal dom delay a -> Int)
    -> (forall a. Eq a => a -> DSignal dom delay a -> Bool)
    -> (forall a. Ord a => DSignal dom delay a -> a)
    -> (forall a. Ord a => DSignal dom delay a -> a)
    -> (forall a. Num a => DSignal dom delay a -> a)
    -> (forall a. Num a => DSignal dom delay a -> a)
    -> Foldable (DSignal dom delay)
    forall a. Eq a => a -> DSignal dom delay a -> Bool
    forall a. Num a => DSignal dom delay a -> a
    forall a. Ord a => DSignal dom delay a -> a
    forall m. Monoid m => DSignal dom delay m -> m
    forall a. DSignal dom delay a -> Bool
    forall a. DSignal dom delay a -> Int
    forall a. DSignal dom delay a -> [a]
    forall a. (a -> a -> a) -> DSignal dom delay a -> a
    forall m a. Monoid m => (a -> m) -> DSignal dom delay a -> m
    forall b a. (b -> a -> b) -> b -> DSignal dom delay a -> b
    forall a b. (a -> b -> b) -> b -> DSignal dom delay a -> b
    forall (dom :: Domain) (delay :: Nat) a.
    Eq a =>
    a -> DSignal dom delay a -> Bool
    forall (dom :: Domain) (delay :: Nat) a.
    Num a =>
    DSignal dom delay a -> a
    forall (dom :: Domain) (delay :: Nat) a.
    Ord a =>
    DSignal dom delay a -> a
    forall (dom :: Domain) (delay :: Nat) m.
    Monoid m =>
    DSignal dom delay m -> m
    forall (dom :: Domain) (delay :: Nat) a.
    DSignal dom delay a -> Bool
    forall (dom :: Domain) (delay :: Nat) a. DSignal dom delay a -> Int
    forall (dom :: Domain) (delay :: Nat) a. DSignal dom delay a -> [a]
    forall (dom :: Domain) (delay :: Nat) a.
    (a -> a -> a) -> DSignal dom delay a -> a
    forall (dom :: Domain) (delay :: Nat) m a.
    Monoid m =>
    (a -> m) -> DSignal dom delay a -> m
    forall (dom :: Domain) (delay :: Nat) b a.
    (b -> a -> b) -> b -> DSignal dom delay a -> b
    forall (dom :: Domain) (delay :: Nat) a b.
    (a -> b -> b) -> b -> DSignal dom delay a -> b
    forall (t :: Type -> Type).
    (forall m. Monoid m => t m -> m)
    -> (forall m a. Monoid m => (a -> m) -> t a -> m)
    -> (forall m a. Monoid m => (a -> m) -> t a -> m)
    -> (forall a b. (a -> b -> b) -> b -> t a -> b)
    -> (forall a b. (a -> b -> b) -> b -> t a -> b)
    -> (forall b a. (b -> a -> b) -> b -> t a -> b)
    -> (forall b a. (b -> a -> b) -> b -> t a -> b)
    -> (forall a. (a -> a -> a) -> t a -> a)
    -> (forall a. (a -> a -> a) -> t a -> a)
    -> (forall a. t a -> [a])
    -> (forall a. t a -> Bool)
    -> (forall a. t a -> Int)
    -> (forall a. Eq a => a -> t a -> Bool)
    -> (forall a. Ord a => t a -> a)
    -> (forall a. Ord a => t a -> a)
    -> (forall a. Num a => t a -> a)
    -> (forall a. Num a => t a -> a)
    -> Foldable t
    $cfold :: forall (dom :: Domain) (delay :: Nat) m.
    Monoid m =>
    DSignal dom delay m -> m
    fold :: forall m. Monoid m => DSignal dom delay m -> m
    $cfoldMap :: forall (dom :: Domain) (delay :: Nat) m a.
    Monoid m =>
    (a -> m) -> DSignal dom delay a -> m
    foldMap :: forall m a. Monoid m => (a -> m) -> DSignal dom delay a -> m
    $cfoldMap' :: forall (dom :: Domain) (delay :: Nat) m a.
    Monoid m =>
    (a -> m) -> DSignal dom delay a -> m
    foldMap' :: forall m a. Monoid m => (a -> m) -> DSignal dom delay a -> m
    $cfoldr :: forall (dom :: Domain) (delay :: Nat) a b.
    (a -> b -> b) -> b -> DSignal dom delay a -> b
    foldr :: forall a b. (a -> b -> b) -> b -> DSignal dom delay a -> b
    $cfoldr' :: forall (dom :: Domain) (delay :: Nat) a b.
    (a -> b -> b) -> b -> DSignal dom delay a -> b
    foldr' :: forall a b. (a -> b -> b) -> b -> DSignal dom delay a -> b
    $cfoldl :: forall (dom :: Domain) (delay :: Nat) b a.
    (b -> a -> b) -> b -> DSignal dom delay a -> b
    foldl :: forall b a. (b -> a -> b) -> b -> DSignal dom delay a -> b
    $cfoldl' :: forall (dom :: Domain) (delay :: Nat) b a.
    (b -> a -> b) -> b -> DSignal dom delay a -> b
    foldl' :: forall b a. (b -> a -> b) -> b -> DSignal dom delay a -> b
    $cfoldr1 :: forall (dom :: Domain) (delay :: Nat) a.
    (a -> a -> a) -> DSignal dom delay a -> a
    foldr1 :: forall a. (a -> a -> a) -> DSignal dom delay a -> a
    $cfoldl1 :: forall (dom :: Domain) (delay :: Nat) a.
    (a -> a -> a) -> DSignal dom delay a -> a
    foldl1 :: forall a. (a -> a -> a) -> DSignal dom delay a -> a
    $ctoList :: forall (dom :: Domain) (delay :: Nat) a. DSignal dom delay a -> [a]
    toList :: forall a. DSignal dom delay a -> [a]
    $cnull :: forall (dom :: Domain) (delay :: Nat) a.
    DSignal dom delay a -> Bool
    null :: forall a. DSignal dom delay a -> Bool
    $clength :: forall (dom :: Domain) (delay :: Nat) a. DSignal dom delay a -> Int
    length :: forall a. DSignal dom delay a -> Int
    $celem :: forall (dom :: Domain) (delay :: Nat) a.
    Eq a =>
    a -> DSignal dom delay a -> Bool
    elem :: forall a. Eq a => a -> DSignal dom delay a -> Bool
    $cmaximum :: forall (dom :: Domain) (delay :: Nat) a.
    Ord a =>
    DSignal dom delay a -> a
    maximum :: forall a. Ord a => DSignal dom delay a -> a
    $cminimum :: forall (dom :: Domain) (delay :: Nat) a.
    Ord a =>
    DSignal dom delay a -> a
    minimum :: forall a. Ord a => DSignal dom delay a -> a
    $csum :: forall (dom :: Domain) (delay :: Nat) a.
    Num a =>
    DSignal dom delay a -> a
    sum :: forall a. Num a => DSignal dom delay a -> a
    $cproduct :: forall (dom :: Domain) (delay :: Nat) a.
    Num a =>
    DSignal dom delay a -> a
    product :: forall a. Num a => DSignal dom delay a -> a
    Foldable, Functor (DSignal dom delay)
    Foldable (DSignal dom delay)
    (Functor (DSignal dom delay), Foldable (DSignal dom delay)) =>
    (forall (f :: Type -> Type) a b.
     Applicative f =>
     (a -> f b) -> DSignal dom delay a -> f (DSignal dom delay b))
    -> (forall (f :: Type -> Type) a.
        Applicative f =>
        DSignal dom delay (f a) -> f (DSignal dom delay a))
    -> (forall (m :: Type -> Type) a b.
        Monad m =>
        (a -> m b) -> DSignal dom delay a -> m (DSignal dom delay b))
    -> (forall (m :: Type -> Type) a.
        Monad m =>
        DSignal dom delay (m a) -> m (DSignal dom delay a))
    -> Traversable (DSignal dom delay)
    forall (dom :: Domain) (delay :: Nat). Functor (DSignal dom delay)
    forall (dom :: Domain) (delay :: Nat). Foldable (DSignal dom delay)
    forall (dom :: Domain) (delay :: Nat) (m :: Type -> Type) a.
    Monad m =>
    DSignal dom delay (m a) -> m (DSignal dom delay a)
    forall (dom :: Domain) (delay :: Nat) (f :: Type -> Type) a.
    Applicative f =>
    DSignal dom delay (f a) -> f (DSignal dom delay a)
    forall (dom :: Domain) (delay :: Nat) (m :: Type -> Type) a b.
    Monad m =>
    (a -> m b) -> DSignal dom delay a -> m (DSignal dom delay b)
    forall (dom :: Domain) (delay :: Nat) (f :: Type -> Type) a b.
    Applicative f =>
    (a -> f b) -> DSignal dom delay a -> f (DSignal dom delay b)
    forall (t :: Type -> Type).
    (Functor t, Foldable t) =>
    (forall (f :: Type -> Type) a b.
     Applicative f =>
     (a -> f b) -> t a -> f (t b))
    -> (forall (f :: Type -> Type) a.
        Applicative f =>
        t (f a) -> f (t a))
    -> (forall (m :: Type -> Type) a b.
        Monad m =>
        (a -> m b) -> t a -> m (t b))
    -> (forall (m :: Type -> Type) a. Monad m => t (m a) -> m (t a))
    -> Traversable t
    forall (m :: Type -> Type) a.
    Monad m =>
    DSignal dom delay (m a) -> m (DSignal dom delay a)
    forall (f :: Type -> Type) a.
    Applicative f =>
    DSignal dom delay (f a) -> f (DSignal dom delay a)
    forall (m :: Type -> Type) a b.
    Monad m =>
    (a -> m b) -> DSignal dom delay a -> m (DSignal dom delay b)
    forall (f :: Type -> Type) a b.
    Applicative f =>
    (a -> f b) -> DSignal dom delay a -> f (DSignal dom delay b)
    $ctraverse :: forall (dom :: Domain) (delay :: Nat) (f :: Type -> Type) a b.
    Applicative f =>
    (a -> f b) -> DSignal dom delay a -> f (DSignal dom delay b)
    traverse :: forall (f :: Type -> Type) a b.
    Applicative f =>
    (a -> f b) -> DSignal dom delay a -> f (DSignal dom delay b)
    $csequenceA :: forall (dom :: Domain) (delay :: Nat) (f :: Type -> Type) a.
    Applicative f =>
    DSignal dom delay (f a) -> f (DSignal dom delay a)
    sequenceA :: forall (f :: Type -> Type) a.
    Applicative f =>
    DSignal dom delay (f a) -> f (DSignal dom delay a)
    $cmapM :: forall (dom :: Domain) (delay :: Nat) (m :: Type -> Type) a b.
    Monad m =>
    (a -> m b) -> DSignal dom delay a -> m (DSignal dom delay b)
    mapM :: forall (m :: Type -> Type) a b.
    Monad m =>
    (a -> m b) -> DSignal dom delay a -> m (DSignal dom delay b)
    $csequence :: forall (dom :: Domain) (delay :: Nat) (m :: Type -> Type) a.
    Monad m =>
    DSignal dom delay (m a) -> m (DSignal dom delay a)
    sequence :: forall (m :: Type -> Type) a.
    Monad m =>
    DSignal dom delay (m a) -> m (DSignal dom delay a)
    Traversable, Gen (DSignal dom delay a)
    Gen (DSignal dom delay a)
    -> (DSignal dom delay a -> [DSignal dom delay a])
    -> Arbitrary (DSignal dom delay a)
    DSignal dom delay a -> [DSignal dom delay a]
    forall a. Gen a -> (a -> [a]) -> Arbitrary a
    forall (dom :: Domain) (delay :: Nat) a.
    Arbitrary a =>
    Gen (DSignal dom delay a)
    forall (dom :: Domain) (delay :: Nat) a.
    Arbitrary a =>
    DSignal dom delay a -> [DSignal dom delay a]
    $carbitrary :: forall (dom :: Domain) (delay :: Nat) a.
    Arbitrary a =>
    Gen (DSignal dom delay a)
    arbitrary :: Gen (DSignal dom delay a)
    $cshrink :: forall (dom :: Domain) (delay :: Nat) a.
    Arbitrary a =>
    DSignal dom delay a -> [DSignal dom delay a]
    shrink :: DSignal dom delay a -> [DSignal dom delay a]
    Arbitrary, (forall b. DSignal dom delay a -> Gen b -> Gen b)
    -> CoArbitrary (DSignal dom delay a)
    forall b. DSignal dom delay a -> Gen b -> Gen b
    forall a. (forall b. a -> Gen b -> Gen b) -> CoArbitrary a
    forall (dom :: Domain) (delay :: Nat) a b.
    CoArbitrary a =>
    DSignal dom delay a -> Gen b -> Gen b
    $ccoarbitrary :: forall (dom :: Domain) (delay :: Nat) a b.
    CoArbitrary a =>
    DSignal dom delay a -> Gen b -> Gen b
    coarbitrary :: forall b. DSignal dom delay a -> Gen b -> Gen b
    CoArbitrary, (forall (m :: Type -> Type).
     Quote m =>
     DSignal dom delay a -> m Exp)
    -> (forall (m :: Type -> Type).
        Quote m =>
        DSignal dom delay a -> Code m (DSignal dom delay a))
    -> Lift (DSignal dom delay a)
    forall t.
    (forall (m :: Type -> Type). Quote m => t -> m Exp)
    -> (forall (m :: Type -> Type). Quote m => t -> Code m t) -> Lift t
    forall (dom :: Domain) (delay :: Nat) a (m :: Type -> Type).
    (Lift a, Quote m) =>
    DSignal dom delay a -> m Exp
    forall (dom :: Domain) (delay :: Nat) a (m :: Type -> Type).
    (Lift a, Quote m) =>
    DSignal dom delay a -> Code m (DSignal dom delay a)
    forall (m :: Type -> Type). Quote m => DSignal dom delay a -> m Exp
    forall (m :: Type -> Type).
    Quote m =>
    DSignal dom delay a -> Code m (DSignal dom delay a)
    $clift :: forall (dom :: Domain) (delay :: Nat) a (m :: Type -> Type).
    (Lift a, Quote m) =>
    DSignal dom delay a -> m Exp
    lift :: forall (m :: Type -> Type). Quote m => DSignal dom delay a -> m Exp
    $cliftTyped :: forall (dom :: Domain) (delay :: Nat) a (m :: Type -> Type).
    (Lift a, Quote m) =>
    DSignal dom delay a -> Code m (DSignal dom delay a)
    liftTyped :: forall (m :: Type -> Type).
    Quote m =>
    DSignal dom delay a -> Code m (DSignal dom delay a)
    Lift )

    -- | Create a 'DSignal' from a list
    --
    -- Every element in the list will correspond to a value of the signal for one
    -- clock cycle.
    --
    -- >>> sampleN 2 (toSignal (dfromList [1,2,3,4,5]))
    -- [1,2]
    --
    -- __NB__: This function is not synthesizable
    dfromList :: NFDataX a => [a] -> DSignal dom 0 a
    dfromList :: forall a (dom :: Domain). NFDataX a => [a] -> DSignal dom 0 a
    dfromList = Signal dom a -> DSignal dom 0 a
    forall a b. Coercible a b => a -> b
    coerce (Signal dom a -> DSignal dom 0 a)
    -> ([a] -> Signal dom a) -> [a] -> DSignal dom 0 a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> Signal dom a
    forall a (dom :: Domain). NFDataX a => [a] -> Signal dom a
    fromList

    -- | Create a 'DSignal' from a list
    --
    -- Every element in the list will correspond to a value of the signal for one
    -- clock cycle.
    --
    -- >>> sampleN 2 (toSignal (dfromList [1,2,3,4,5]))
    -- [1,2]
    --
    -- __NB__: This function is not synthesizable
    dfromList_lazy :: [a] -> DSignal dom 0 a
    dfromList_lazy :: forall a (dom :: Domain). [a] -> DSignal dom 0 a
    dfromList_lazy = Signal dom a -> DSignal dom 0 a
    forall a b. Coercible a b => a -> b
    coerce (Signal dom a -> DSignal dom 0 a)
    -> ([a] -> Signal dom a) -> [a] -> DSignal dom 0 a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> Signal dom a
    forall a (dom :: Domain). [a] -> Signal dom a
    fromList_lazy

    -- | Feed the delayed result of a function back to its input:
    --
    -- @
    -- mac
    --   :: forall dom
    --    . KnownDomain dom
    --   => Clock dom
    --   -> Reset dom
    --   -> Enable dom
    --   -> 'DSignal' dom 0 Int
    --   -> 'DSignal' dom 0 Int
    --   -> 'DSignal' dom 0 Int
    -- mac clk rst en x y = 'feedback' (mac' x y)
    --   where
    --     mac'
    --       :: 'DSignal' dom 0 Int
    --       -> 'DSignal' dom 0 Int
    --       -> 'DSignal' dom 0 Int
    --       -> ('DSignal' dom 0 Int, 'DSignal' dom 1 Int)
    --     mac' a b acc = let acc' = a * b + acc
    --                    in  (acc, 'Clash.Explicit.Signal.Delayed.delayedI' clk rst en 0 acc')
    -- @
    --
    -- >>> sampleN 7 (toSignal (mac systemClockGen systemResetGen enableGen (dfromList [0..]) (dfromList [0..])))
    -- [0,0,1,5,14,30,55]
    feedback
      :: (DSignal dom n a -> (DSignal dom n a,DSignal dom (n + m + 1) a))
      -> DSignal dom n a
    feedback :: forall (dom :: Domain) (n :: Nat) a (m :: Nat).
    (DSignal dom n a -> (DSignal dom n a, DSignal dom ((n + m) + 1) a))
    -> DSignal dom n a
    feedback DSignal dom n a -> (DSignal dom n a, DSignal dom ((n + m) + 1) a)
    f = let (DSignal dom n a
    o,DSignal dom ((n + m) + 1) a
    r) = DSignal dom n a -> (DSignal dom n a, DSignal dom ((n + m) + 1) a)
    f (DSignal dom ((n + m) + 1) a -> DSignal dom n a
    forall a b. Coercible a b => a -> b
    coerce DSignal dom ((n + m) + 1) a
    r) in DSignal dom n a
    o

    -- | 'Signal's are not delayed
    fromSignal :: Signal dom a -> DSignal dom 0 a
    fromSignal :: forall (dom :: Domain) a. Signal dom a -> DSignal dom 0 a
    fromSignal = Signal dom a -> DSignal dom 0 a
    forall a b. Coercible a b => a -> b
    coerce

    -- | __EXPERIMENTAL__
    --
    -- __Unsafely__ convert a 'Signal' to a 'DSignal' with an arbitrary @delay@.
    --
    -- __NB__: Should only be used to interface with functions specified in terms of
    -- 'Signal'.
    unsafeFromSignal :: Signal dom a -> DSignal dom n a
    unsafeFromSignal :: forall (dom :: Domain) a (n :: Nat).
    Signal dom a -> DSignal dom n a
    unsafeFromSignal = Signal dom a -> DSignal dom n a
    forall (dom :: Domain) (delay :: Nat) a.
    Signal dom a -> DSignal dom delay a
    DSignal

    -- | __EXPERIMENTAL__
    --
    -- Access a /delayed/ signal from the future in the present. Often required
    -- When writing a circuit that requires feedback from itself.
    --
    -- @
    -- mac
    --   :: KnownDomain dom
    --   => Clock dom
    --   -> Reset dom
    --   -> Enable dom
    --   -> 'DSignal' dom 0 Int
    --   -> 'DSignal' dom 0 Int
    --   -> 'DSignal' dom 0 Int
    -- mac clk rst en x y = acc'
    --   where
    --     acc' = (x * y) + 'antiDelay' d1 acc
    --     acc  = 'Clash.Explicit.Signal.Delayed.delayedI' clk rst en 0 acc'
    -- @
    antiDelay :: SNat d -> DSignal dom (n + d) a -> DSignal dom n a
    antiDelay :: forall (d :: Nat) (dom :: Domain) (n :: Nat) a.
    SNat d -> DSignal dom (n + d) a -> DSignal dom n a
    antiDelay SNat d
    _ = DSignal dom (n + d) a -> DSignal dom n a
    forall a b. Coercible a b => a -> b
    coerce

    -- | __EXPERIMENTAL__
    --
    -- Access a /delayed/ signal from the past in the present. In contrast with
    -- 'Clash.Explicit.Signal.Delayed.delayed' and friends forward does not insert
    -- any logic. This means using this function violates the delay invariant of
    -- 'DSignal'. This is sometimes useful when combining unrelated delayed signals
    -- where inserting logic is not wanted or when abstracting over internal
    -- delayed signals where the internal delay information should not be leaked.
    --
    -- For example, the circuit below returns a sequence of numbers as a pair
    -- but the internal delay information between the elements of the pair
    -- should not leak into the type.
    --
    -- @
    -- numbers
    --   :: forall dom
    --    . KnownDomain dom
    --   => Clock dom
    --   -> Reset dom
    --   -> Enable dom
    --   -> 'DSignal' dom 5 (Int, Int)
    -- numbers clk rst en = DB.bundle (forward d1 s1, s2)
    --   where
    --     s1 :: 'DSignal' dom 4 Int
    --     s1 = 'Clash.Explicit.Signal.Delayed.delayed' clk rst en (100 :> 10 :> 5 :> 1 :> Nil) (pure 200)
    --     s2 :: 'DSignal' dom 5 Int
    --     s2 = fmap (2*) $ 'Clash.Explicit.Signal.Delayed.delayN' d1 0 en clk s1
    -- @
    --
    -- >>> sampleN 8 (toSignal (numbers systemClockGen systemResetGen enableGen))
    -- [(1,0),(1,2),(5,2),(10,10),(100,20),(200,200),(200,400),(200,400)]

    forward :: SNat d -> DSignal dom n a -> DSignal dom (n + d) a
    forward :: forall (d :: Nat) (dom :: Domain) (n :: Nat) a.
    SNat d -> DSignal dom n a -> DSignal dom (n + d) a
    forward SNat d
    _ = DSignal dom n a -> DSignal dom (n + d) a
    forall a b. Coercible a b => a -> b
    coerce