    {-|
    Copyright  :  (C) 2016,      University of Twente,
                      2017,      QBayLogic, Google Inc.
                      2017-2019, Myrtle Software Ltd,
                      2021-2025, QBayLogic B.V.
    License    :  BSD2 (see the file LICENSE)
    Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>

    'XException': An exception for uninitialized values

    >>> show (errorX "No value here" :: Integer, 4 :: Int)
    "(*** Exception: X: No value here
    CallStack (from HasCallStack):
    ...
    >>> showX (errorX "No value here" :: Integer, 4 :: Int)
    "(undefined,4)"
    -}

    {-# LANGUAGE CPP #-}
    {-# LANGUAGE EmptyCase #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE GADTs #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE NoImplicitPrelude #-}
    {-# LANGUAGE StandaloneDeriving #-}
    {-# LANGUAGE TemplateHaskell #-}

    {-# LANGUAGE Trustworthy #-}

    module Clash.XException
      ( -- * 'XException': An exception for uninitialized values
        XException(..), errorX, isX, hasX, maybeIsX, maybeHasX, fromJustX, undefined,
        xToErrorCtx, xToError
        -- * Printing 'XException's as @undefined@
      , ShowX (..), showsX, printX, showsPrecXWith
        -- * Strict evaluation
      , seqX, seqErrorX, forceX, deepseqX, rwhnfX, defaultSeqX, hwSeqX
        -- * Structured undefined / deep evaluation with undefined values
      , NFDataX (rnfX, deepErrorX, hasUndefined, ensureSpine)
      )
    where

    import           Prelude             hiding (undefined)

    import           Clash.Annotations.Primitive (hasBlackBox)
    import           Clash.CPP           (maxTupleSize, fSuperStrict)
    import           Clash.XException.Internal
    import           Clash.XException.TH
    import           Control.Exception
      (ErrorCall (..), Handler(..), catch, catches, evaluate, throw)
    import           Control.DeepSeq     (NFData, rnf)
    import           Data.Complex        (Complex)
    import           Data.Either         (isLeft)
    import           Data.Foldable       (toList)
    import           Data.Functor.Compose (Compose)
    import           Data.Functor.Const  (Const)
    import           Data.Functor.Identity (Identity)
    import           Data.Functor.Product (Product)
    import           Data.Functor.Sum    (Sum)
    import           Data.Int            (Int8, Int16, Int32, Int64)
    import qualified Data.List.Infinite  as Inf
    import           Data.List.Infinite  (Infinite (..))
    import           Data.List.NonEmpty  (NonEmpty)
    import           Data.Ord            (Down (Down))
    import           Data.Proxy          (Proxy)
    import           Data.Ratio          (Ratio, numerator, denominator)
    import qualified Data.Semigroup      as SG
    import qualified Data.Monoid         as M
    import           Data.Sequence       (Seq(Empty, (:<|)))
    import           Data.Word           (Word8, Word16, Word32, Word64)
    import           Foreign.C.Types     (CUShort)
    import           GHC.Generics
    import           GHC.Natural         (Natural)
    import           GHC.Stack
      (HasCallStack, callStack, prettyCallStack, withFrozenCallStack)
    import           Numeric.Half        (Half)
    import           System.IO.Unsafe    (unsafeDupablePerformIO)

    -- $setup
    -- >>> :m -Prelude
    -- >>> import Clash.Prelude
    -- >>> import Clash.Class.BitPack (pack)
    -- >>> import Clash.Sized.Vector (Vec)
    -- >>> import Clash.Sized.RTree (RTree)
    -- >>> :set -fplugin GHC.TypeLits.Normalise
    -- >>> :set -fplugin GHC.TypeLits.KnownNat.Solver

    -- | Either 'seqX' or 'deepseqX' depending on the value of the cabal flag
    -- '-fsuper-strict'. If enabled, 'defaultSeqX' will be 'deepseqX', otherwise
    -- 'seqX'. Flag defaults to /false/ and thus 'seqX'.
    defaultSeqX :: NFDataX a => a -> b -> b
    defaultSeqX :: forall a b. NFDataX a => a -> b -> b
    defaultSeqX = if Bool
    fSuperStrict then a -> b -> b
    forall a b. NFDataX a => a -> b -> b
    deepseqX else a -> b -> b
    forall a b. a -> b -> b
    seqX
    {-# INLINE defaultSeqX #-}
    infixr 0 `defaultSeqX`

    -- | Like 'error', but throwing an 'XException' instead of an 'ErrorCall'
    --
    -- The 'ShowX' methods print these error-values as @undefined@; instead of error'ing
    -- out with an exception.
    errorX :: HasCallStack => String -> a
    errorX :: forall a. HasCallStack => String -> a
    errorX String
    msg = XException -> a
    forall a e. (HasCallStack, Exception e) => e -> a
    throw (String -> XException
    XException (String
    "X: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    msg String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "\n" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ CallStack -> String
    prettyCallStack CallStack
    HasCallStack => CallStack
    callStack))
    {-# NOINLINE errorX #-}
    {-# ANN errorX hasBlackBox #-}

    -- | Convert 'XException' to 'ErrorCall'
    --
    -- This is useful when tracking the source of 'XException' that gets eaten up by
    -- 'Clash.Classes.BitPack.pack' inside of your circuit; since
    -- 'Clash.Classes.BitPack.pack' translates 'XException' into undefined bits.
    --
    -- So for example if you have some large function f:
    --
    -- > f a b = ... pack a ... pack b ...
    --
    -- Where it is basically an error if either /a/ or /b/ ever throws an 'XException',
    -- and so you want that to be reported the moment /a/ or /b/ is used, instead of
    -- it being thrown when evaluating the result of /f/, then do:
    --
    -- > {-# LANGUAGE ViewPatterns #-}
    -- > f (xToErrorCtx "a is X" -> a) (xToErrorCtx "b is X" -> b) = ...
    --
    -- Where we pass an extra string, for context, to know which argument evaluated
    -- to an 'XException'. We can also use BangPatterns to report the potential
    -- 'XException' being thrown by /a/ or /b/ even earlier, i.e. when /f/ is applied:
    --
    -- > {-# LANGUAGE ViewPatterns, BangPatterns #-}
    -- > f (xToErrorCtx "a is X" -> !a) (xToErrorCtx "b is X" -> !b) = ...
    --
    -- __NB__: Fully synthesizable, so doesn't have to be removed before synthesis
    --
    -- === __Example__
    --
    -- >>> :set -XViewPatterns -XDataKinds
    -- >>> import Clash.Sized.BitVector
    -- >>> import GHC.Stack
    -- >>> :{
    -- let h, h' :: Bit -> BitVector 8 -> BitVector 8
    --     h (xToErrorCtx "a is X" -> a) (xToErrorCtx "b is X" -> b) = slice d7 d0 (pack a ++# b)
    --     h' a b = slice d7 d0 (pack a ++# b)
    -- :}
    --
    -- >>> h' (errorX "QQ") 3
    -- 0b0000_0011
    -- >>> h (errorX "QQ") 3
    -- *** Exception: a is X
    -- X: QQ
    -- CallStack (from HasCallStack):
    --   errorX, called at ...
    -- <BLANKLINE>
    xToErrorCtx :: String -> a -> a
    xToErrorCtx :: forall a. String -> a -> a
    xToErrorCtx String
    ctx a
    a = IO a -> a
    forall a. IO a -> a
    unsafeDupablePerformIO
      (IO a -> (XException -> IO a) -> IO a
    forall e a. Exception e => IO a -> (e -> IO a) -> IO a
    catch (a -> IO a
    forall a. a -> IO a
    evaluate a
    a IO a -> IO a -> IO a
    forall a b. IO a -> IO b -> IO b
    forall (m :: Type -> Type) a b. Monad m => m a -> m b -> m b
    >> a -> IO a
    forall a. a -> IO a
    forall (m :: Type -> Type) a. Monad m => a -> m a
    return a
    a)
             (\(XException String
    msg) ->
               ErrorCall -> IO a
    forall a e. (HasCallStack, Exception e) => e -> a
    throw (String -> ErrorCall
    ErrorCall ([String] -> String
    unlines [String
    ctx,String
    msg]))))
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE xToErrorCtx #-}

    -- | Convert 'XException' to 'ErrorCall'
    --
    -- This is useful when tracking the source of 'XException' that gets eaten up by
    -- 'Clash.Classes.BitPack.pack' inside of your circuit; since
    -- 'Clash.Classes.BitPack.pack' translates 'XException' into undefined bits.
    --
    -- So for example if you have some large function f:
    --
    -- > f a b = ... pack a ... pack b ...
    --
    -- Where it is basically an error if either /a/ or /b/ ever throws an 'XException',
    -- and so you want that to be reported the moment /a/ or /b/ is used, instead of
    -- it being thrown when evaluating the result of /f/, then do:
    --
    -- > {-# LANGUAGE ViewPatterns #-}
    -- > f (xToError -> a) (xToError -> b) = ...
    --
    -- Unlike 'xToErrorCtx', where we have an extra String argument to distinguish
    -- one call to 'xToError' to the other, 'xToError' will use the 'GHC.CallStack'
    -- mechanism to aid the user in distinguishing different call to 'xToError'.
    -- We can also use BangPatterns to report the potential 'XException' being
    -- thrown by /a/ or /b/ even earlier, i.e. when /f/ is applied:
    --
    -- > {-# LANGUAGE ViewPatterns, BangPatterns #-}
    -- > f (xToError -> !a) (xToError -> !b) = ...
    --
    -- __NB__: Fully synthesizable, so doesn't have to be removed before synthesis
    --
    -- === __Example__
    --
    -- >>> :set -XViewPatterns -XDataKinds
    -- >>> import Clash.Sized.BitVector
    -- >>> import GHC.Stack
    -- >>> :{
    -- let f, g, h, h' :: HasCallStack => Bit -> BitVector 8 -> BitVector 8
    --     f = g
    --     g = h
    --     h (xToError -> a) (xToError -> b) = slice d7 d0 (pack a ++# b)
    --     h' a b = slice d7 d0 (pack a ++# b)
    -- :}
    --
    -- >>> h' (errorX "QQ") 3
    -- 0b0000_0011
    -- >>> f (errorX "QQ") 3
    -- *** Exception: CallStack (from HasCallStack):
    --   xToError, called at ...
    --   h, called at ...
    --   g, called at ...
    --   f, called at ...
    -- X: QQ
    -- CallStack (from HasCallStack):
    --   errorX, called at ...
    -- <BLANKLINE>
    xToError :: HasCallStack => a -> a
    xToError :: forall a. HasCallStack => a -> a
    xToError = String -> a -> a
    forall a. String -> a -> a
    xToErrorCtx (CallStack -> String
    prettyCallStack CallStack
    HasCallStack => CallStack
    callStack)
    {-# INLINE xToError #-}

    -- | Like 'seq', however, whereas 'seq' will always do:
    --
    -- > seq  _|_              b = _|_
    --
    -- 'seqX' will do:
    --
    -- > seqX (XException msg) b = b
    -- > seqX _|_              b = _|_
    seqX :: a -> b -> b
    seqX :: forall a b. a -> b -> b
    seqX a
    a b
    b = IO b -> b
    forall a. IO a -> a
    unsafeDupablePerformIO
      (IO b -> (XException -> IO b) -> IO b
    forall e a. Exception e => IO a -> (e -> IO a) -> IO a
    catch (a -> IO a
    forall a. a -> IO a
    evaluate a
    a IO a -> IO b -> IO b
    forall a b. IO a -> IO b -> IO b
    forall (m :: Type -> Type) a b. Monad m => m a -> m b -> m b
    >> b -> IO b
    forall a. a -> IO a
    forall (m :: Type -> Type) a. Monad m => a -> m a
    return b
    b) (\(XException String
    _) -> b -> IO b
    forall a. a -> IO a
    forall (m :: Type -> Type) a. Monad m => a -> m a
    return b
    b))
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE seqX #-}
    {-# ANN seqX hasBlackBox #-}
    infixr 0 `seqX`

    -- | Like 'seqX', but will also catch ErrorCall exceptions which are thrown.
    -- This should be used with care.
    --
    -- > seqErrorX (ErrorCall msg)  b = b
    -- > seqErrorX (XException msg) b = b
    -- > seqErrorX _|_              b = _|_
    seqErrorX :: a -> b -> b
    seqErrorX :: forall a b. a -> b -> b
    seqErrorX a
    a b
    b = IO b -> b
    forall a. IO a -> a
    unsafeDupablePerformIO
      ((a -> IO a
    forall a. a -> IO a
    evaluate a
    a IO a -> IO b -> IO b
    forall a b. IO a -> IO b -> IO b
    forall (m :: Type -> Type) a b. Monad m => m a -> m b -> m b
    >> b -> IO b
    forall a. a -> IO a
    forall (m :: Type -> Type) a. Monad m => a -> m a
    return b
    b) IO b -> [Handler b] -> IO b
    forall a. IO a -> [Handler a] -> IO a
    `catches`
         [ (XException -> IO b) -> Handler b
    forall a e. Exception e => (e -> IO a) -> Handler a
    Handler (\(XException String
    _) -> b -> IO b
    forall a. a -> IO a
    forall (m :: Type -> Type) a. Monad m => a -> m a
    return b
    b)
         , (ErrorCall -> IO b) -> Handler b
    forall a e. Exception e => (e -> IO a) -> Handler a
    Handler (\(ErrorCall String
    _) -> b -> IO b
    forall a. a -> IO a
    forall (m :: Type -> Type) a. Monad m => a -> m a
    return b
    b)
         ])
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE seqErrorX #-}
    {-# ANN seqErrorX hasBlackBox #-}
    infixr 0 `seqErrorX`

    -- | Like 'seqX' in simulation, but will force its first argument to be rendered
    -- in HDL. This is useful for components that need to be rendered in hardware,
    -- but otherwise have no meaning in simulation. An example of such a component
    -- would be an ILA: a component monitoring an internal signal of a design. The
    -- output of such a component (typically a unit) can be passed as the first
    -- argument to 'hwSeqX' to ensure the ILA ends up in the generated HDL.
    --
    -- __NB__: The result of 'hwSeqX' must (indirectly) be used at the very top of
    -- a design. If it's not, Clash will remove it like it does for any other unused
    -- circuit parts.
    --
    -- __NB__: Make sure the blackbox for the component with zero-width results
    -- uses 'Clash.Netlist.BlackBox.Types.RenderVoid'
    hwSeqX :: a -> b -> b
    hwSeqX :: forall a b. a -> b -> b
    hwSeqX = a -> b -> b
    forall a b. a -> b -> b
    seqX
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE hwSeqX #-}
    {-# ANN hwSeqX hasBlackBox #-}
    infixr 0 `hwSeqX`

    -- | Evaluate a value with given function, returning 'Nothing' if it throws
    -- 'XException'. Note that non-'XException' errors take precedence over 'XException'
    -- ones
    --
    -- > maybeX hasX 42                    = Just 42
    -- > maybeX hasX (XException msg)      = Nothing
    -- > maybeX hasX (3, XException msg)   = Nothing
    -- > maybeX hasX (XException msg, _|_) = _|_
    -- > maybeX hasX (_|_, XException msg) = _|_
    -- > maybeX hasX (3, _|_)              = _|_
    -- > maybeX hasX _|_                   = _|_
    -- >
    -- > maybeX isX 42                  = Just 42
    -- > maybeX isX (XException msg)    = Nothing
    -- > maybeX isX (3, XException msg) = Just (3, XException msg)
    -- > maybeX isX (3, _|_)            = Just (3, _|_)
    -- > maybeX isX _|_                 = _|_
    --
    maybeX :: (a -> Either String a) -> a -> Maybe a
    maybeX :: forall a. (a -> Either String a) -> a -> Maybe a
    maybeX a -> Either String a
    f a
    a = (String -> Maybe a) -> (a -> Maybe a) -> Either String a -> Maybe a
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (Maybe a -> String -> Maybe a
    forall a b. a -> b -> a
    const Maybe a
    forall a. Maybe a
    Nothing) a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Either String a
    f a
    a)

    -- | Fully evaluate a value, returning 'Nothing' if it throws 'XException'. Note
    -- that non-'XException' errors take precedence over 'XException' ones.
    --
    -- > maybeHasX 42                    = Just 42
    -- > maybeHasX (XException msg)      = Nothing
    -- > maybeHasX (3, XException msg)   = Nothing
    -- > maybeHasX (XException msg, _|_) = _|_
    -- > maybeHasX (_|_, XException msg) = _|_
    -- > maybeHasX (3, _|_)              = _|_
    -- > maybeHasX _|_                   = _|_
    --
    maybeHasX :: (NFData a, NFDataX a) => a -> Maybe a
    maybeHasX :: forall a. (NFData a, NFDataX a) => a -> Maybe a
    maybeHasX = (a -> Either String a) -> a -> Maybe a
    forall a. (a -> Either String a) -> a -> Maybe a
    maybeX a -> Either String a
    forall a. (NFData a, NFDataX a) => a -> Either String a
    hasX

    -- | Evaluate a value to WHNF, returning 'Nothing' if it throws 'XException'.
    --
    -- > maybeIsX 42                  = Just 42
    -- > maybeIsX (XException msg)    = Nothing
    -- > maybeIsX (3, XException msg) = Just (3, XException msg)
    -- > maybeIsX (3, _|_)            = Just (3, _|_)
    -- > maybeIsX _|_                 = _|_
    maybeIsX :: a -> Maybe a
    maybeIsX :: forall a. a -> Maybe a
    maybeIsX = (a -> Either String a) -> a -> Maybe a
    forall a. (a -> Either String a) -> a -> Maybe a
    maybeX a -> Either String a
    forall a. a -> Either String a
    isX

    -- | Fully evaluate a value, returning @'Left' msg@ if it throws 'XException'.
    -- If you want to determine if a value contains undefined parts, use
    -- 'hasUndefined' instead.
    --
    -- > hasX 42                    = Right 42
    -- > hasX (XException msg)      = Left msg
    -- > hasX (3, XException msg)   = Left msg
    -- > hasX (XException msg, _|_) = _|_
    -- > hasX (_|_, XException msg) = _|_
    -- > hasX (3, _|_)              = _|_
    -- > hasX _|_                   = _|_
    --
    -- If a data structure contains multiple 'XException's, the "first" message is
    -- picked according to the implementation of 'rnfX'.
    hasX :: (NFData a, NFDataX a) => a -> Either String a
    hasX :: forall a. (NFData a, NFDataX a) => a -> Either String a
    hasX a
    a =
      -- TODO: Whenever 'a' contains an 'XException', we need to reevaluate the
      --       structure using 'rnfX' to make sure it didn't also contain another
      --       error call. We could prevent the two traversals by making 'hasX' a
      --       type class method. Also see: https://github.com/clash-lang/clash-compiler/issues/2450.
      IO (Either String a) -> Either String a
    forall a. IO a -> a
    unsafeDupablePerformIO
        (IO (Either String a)
    -> (XException -> IO (Either String a)) -> IO (Either String a)
    forall e a. Exception e => IO a -> (e -> IO a) -> IO a
    catch
          (() -> IO ()
    forall a. a -> IO a
    evaluate (a -> ()
    forall a. NFData a => a -> ()
    rnf a
    a) IO () -> IO (Either String a) -> IO (Either String a)
    forall a b. IO a -> IO b -> IO b
    forall (m :: Type -> Type) a b. Monad m => m a -> m b -> m b
    >> Either String a -> IO (Either String a)
    forall a. a -> IO a
    forall (m :: Type -> Type) a. Monad m => a -> m a
    return (a -> Either String a
    forall a b. b -> Either a b
    Right a
    a))
          (\(XException String
    msg) -> () -> IO ()
    forall a. a -> IO a
    evaluate (a -> ()
    forall a. NFDataX a => a -> ()
    rnfX a
    a) IO () -> IO (Either String a) -> IO (Either String a)
    forall a b. IO a -> IO b -> IO b
    forall (m :: Type -> Type) a b. Monad m => m a -> m b -> m b
    >> Either String a -> IO (Either String a)
    forall a. a -> IO a
    forall (m :: Type -> Type) a. Monad m => a -> m a
    return (String -> Either String a
    forall a b. a -> Either a b
    Left String
    msg)))
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE hasX #-}

    -- | Evaluate a value to WHNF, returning @'Left' msg@ if is a 'XException'.
    --
    -- > isX 42                  = Right 42
    -- > isX (XException msg)    = Left msg
    -- > isX (3, XException msg) = Right (3, XException msg)
    -- > isX (3, _|_)            = Right (3, _|_)
    -- > isX _|_                 = _|_
    isX :: a -> Either String a
    isX :: forall a. a -> Either String a
    isX a
    a =
      IO (Either String a) -> Either String a
    forall a. IO a -> a
    unsafeDupablePerformIO
        (IO (Either String a)
    -> (XException -> IO (Either String a)) -> IO (Either String a)
    forall e a. Exception e => IO a -> (e -> IO a) -> IO a
    catch
          (a -> IO a
    forall a. a -> IO a
    evaluate a
    a IO a -> IO (Either String a) -> IO (Either String a)
    forall a b. IO a -> IO b -> IO b
    forall (m :: Type -> Type) a b. Monad m => m a -> m b -> m b
    >> Either String a -> IO (Either String a)
    forall a. a -> IO a
    forall (m :: Type -> Type) a. Monad m => a -> m a
    return (a -> Either String a
    forall a b. b -> Either a b
    Right a
    a))
          (\(XException String
    msg) -> Either String a -> IO (Either String a)
    forall a. a -> IO a
    forall (m :: Type -> Type) a. Monad m => a -> m a
    return (String -> Either String a
    forall a b. a -> Either a b
    Left String
    msg)))
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE isX #-}

    -- | Like the 'Show' class, but values that normally throw an 'XException' are
    -- converted to @undefined@, instead of error'ing out with an exception.
    --
    -- >>> show (errorX "No value here" :: Integer, 4 :: Int)
    -- "(*** Exception: X: No value here
    -- CallStack (from HasCallStack):
    -- ...
    -- >>> showX (errorX "No value here" :: Integer, 4 :: Int)
    -- "(undefined,4)"
    --
    -- Can be derived using 'GHC.Generics':
    --
    -- > {-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
    -- >
    -- > import Clash.Prelude
    -- > import GHC.Generics
    -- >
    -- > data T = MkTA Int | MkTB Bool
    -- >   deriving (Show,Generic,ShowX)
    class ShowX a where
      -- | Like 'showsPrec', but values that normally throw an 'XException' are
      -- converted to @undefined@, instead of error'ing out with an exception.
      showsPrecX :: Int -> a -> ShowS

      -- | Like 'show', but values that normally throw an 'XException' are
      -- converted to @undefined@, instead of error'ing out with an exception.
      showX :: a -> String
      showX a
    x = a -> String -> String
    forall a. ShowX a => a -> String -> String
    showsX a
    x String
    ""

      -- | Like 'showList', but values that normally throw an 'XException' are
      -- converted to @undefined@, instead of error'ing out with an exception.
      showListX :: [a] -> ShowS
      showListX [a]
    ls String
    s = (a -> String -> String) -> [a] -> String -> String
    forall a. (a -> String -> String) -> [a] -> String -> String
    showListX__ a -> String -> String
    forall a. ShowX a => a -> String -> String
    showsX [a]
    ls String
    s

      default showsPrecX :: (Generic a, GShowX (Rep a)) => Int -> a -> ShowS
      showsPrecX = Int -> a -> String -> String
    forall a.
    (Generic a, GShowX (Rep a)) =>
    Int -> a -> String -> String
    genericShowsPrecX

    -- | Like 'print', but values that normally throw an 'XException' are
    -- converted to @undefined@, instead of error'ing out with an exception
    printX :: ShowX a => a -> IO ()
    printX :: forall a. ShowX a => a -> IO ()
    printX a
    x = String -> IO ()
    putStrLn (String -> IO ()) -> String -> IO ()
    forall a b. (a -> b) -> a -> b
    $ a -> String
    forall a. ShowX a => a -> String
    showX a
    x

    instance ShowX ()
    -- | @since 1.8.2
    instance ShowX (Proxy a)
    instance ShowX a => ShowX (Identity a)
    instance ShowX a => ShowX (Const a b)
    instance (ShowX (f a), ShowX (g a)) => ShowX (Product f g a)
    instance (ShowX (f a), ShowX (g a)) => ShowX (Sum f g a)
    instance (ShowX (f (g a))) => ShowX (Compose f g a)

    instance {-# OVERLAPPABLE #-} ShowX a => ShowX [a] where
      showsPrecX :: Int -> [a] -> String -> String
    showsPrecX Int
    _ = [a] -> String -> String
    forall a. ShowX a => [a] -> String -> String
    showListX

    instance ShowX Char where
      showsPrecX :: Int -> Char -> String -> String
    showsPrecX = (Int -> Char -> String -> String)
    -> Int -> Char -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Char -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    instance ShowX Bool

    instance ShowX Double where
      showsPrecX :: Int -> Double -> String -> String
    showsPrecX = (Int -> Double -> String -> String)
    -> Int -> Double -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Double -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    instance ShowX a => ShowX (Down a) where
      showsPrecX :: Int -> Down a -> String -> String
    showsPrecX = (Int -> Down a -> String -> String)
    -> Int -> Down a -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Down a -> String -> String
    forall a. ShowX a => Int -> a -> String -> String
    showsPrecX

    instance (ShowX a, ShowX b) => ShowX (Either a b)

    instance ShowX Float where
      showsPrecX :: Int -> Float -> String -> String
    showsPrecX = (Int -> Float -> String -> String)
    -> Int -> Float -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Float -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    instance ShowX Int where
      showsPrecX :: Int -> Int -> String -> String
    showsPrecX = (Int -> Int -> String -> String) -> Int -> Int -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Int -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    instance ShowX Int8 where
      showsPrecX :: Int -> Int8 -> String -> String
    showsPrecX = (Int -> Int8 -> String -> String)
    -> Int -> Int8 -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Int8 -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    instance ShowX Int16 where
      showsPrecX :: Int -> Int16 -> String -> String
    showsPrecX = (Int -> Int16 -> String -> String)
    -> Int -> Int16 -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Int16 -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    instance ShowX Int32 where
      showsPrecX :: Int -> Int32 -> String -> String
    showsPrecX = (Int -> Int32 -> String -> String)
    -> Int -> Int32 -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Int32 -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    instance ShowX Int64 where
      showsPrecX :: Int -> Int64 -> String -> String
    showsPrecX = (Int -> Int64 -> String -> String)
    -> Int -> Int64 -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Int64 -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    instance ShowX Integer where
      showsPrecX :: Int -> Integer -> String -> String
    showsPrecX = (Int -> Integer -> String -> String)
    -> Int -> Integer -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Integer -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    instance ShowX Natural where
      showsPrecX :: Int -> Natural -> String -> String
    showsPrecX = (Int -> Natural -> String -> String)
    -> Int -> Natural -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Natural -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    instance ShowX Ordering

    instance ShowX a => ShowX (Seq a) where
      showsPrecX :: Int -> Seq a -> String -> String
    showsPrecX Int
    _ = [a] -> String -> String
    forall a. ShowX a => [a] -> String -> String
    showListX ([a] -> String -> String)
    -> (Seq a -> [a]) -> Seq a -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Seq a -> [a]
    forall a. Seq a -> [a]
    forall (t :: Type -> Type) a. Foldable t => t a -> [a]
    toList

    instance ShowX Word where
      showsPrecX :: Int -> Word -> String -> String
    showsPrecX = (Int -> Word -> String -> String)
    -> Int -> Word -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Word -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    instance ShowX Word8 where
      showsPrecX :: Int -> Word8 -> String -> String
    showsPrecX = (Int -> Word8 -> String -> String)
    -> Int -> Word8 -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Word8 -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    instance ShowX Word16 where
      showsPrecX :: Int -> Word16 -> String -> String
    showsPrecX = (Int -> Word16 -> String -> String)
    -> Int -> Word16 -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Word16 -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    instance ShowX Word32 where
      showsPrecX :: Int -> Word32 -> String -> String
    showsPrecX = (Int -> Word32 -> String -> String)
    -> Int -> Word32 -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Word32 -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    instance ShowX Word64 where
      showsPrecX :: Int -> Word64 -> String -> String
    showsPrecX = (Int -> Word64 -> String -> String)
    -> Int -> Word64 -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Word64 -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    instance ShowX a => ShowX (Maybe a)

    instance ShowX a => ShowX (Ratio a) where
      showsPrecX :: Int -> Ratio a -> String -> String
    showsPrecX = (Int -> Ratio a -> String -> String)
    -> Int -> Ratio a -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> Ratio a -> String -> String
    forall a. ShowX a => Int -> a -> String -> String
    showsPrecX

    instance ShowX a => ShowX (Complex a)

    instance {-# OVERLAPPING #-} ShowX String where
      showsPrecX :: Int -> String -> String -> String
    showsPrecX = (Int -> String -> String -> String)
    -> Int -> String -> String -> String
    forall a.
    (Int -> a -> String -> String) -> Int -> a -> String -> String
    showsPrecXWith Int -> String -> String -> String
    forall a. Show a => Int -> a -> String -> String
    showsPrec

    -- | a variant of 'deepseqX' that is useful in some circumstances:
    --
    -- > forceX x = x `deepseqX` x
    forceX :: NFDataX a => a -> a
    forceX :: forall a. NFDataX a => a -> a
    forceX a
    x = a
    x a -> a -> a
    forall a b. NFDataX a => a -> b -> b
    `deepseqX` a
    x
    {-# INLINE forceX #-}

    -- | 'deepseqX': fully evaluates the first argument, before returning the
    -- second. Does not propagate 'XException's.
    deepseqX :: NFDataX a => a -> b -> b
    deepseqX :: forall a b. NFDataX a => a -> b -> b
    deepseqX a
    a b
    b = a -> ()
    forall a. NFDataX a => a -> ()
    rnfX a
    a () -> b -> b
    forall a b. a -> b -> b
    `seq` b
    b
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE deepseqX #-}
    {-# ANN deepseqX hasBlackBox #-}
    infixr 0 `deepseqX`

    -- | Reduce to weak head normal form
    --
    -- Equivalent to @\\x -> 'seqX' x ()@.
    --
    -- Useful for defining 'NFDataX.rnfX' for types for which NF=WHNF holds.
    rwhnfX :: a -> ()
    rwhnfX :: forall a. a -> ()
    rwhnfX = (a -> () -> ()
    forall a b. a -> b -> b
    `seqX` ())
    {-# INLINE rwhnfX #-}

    -- | Class that houses functions dealing with /undefined/ values in Clash. See
    -- 'deepErrorX' and 'rnfX'.
    class NFDataX a where
      -- | Create a value where all the elements have an 'errorX',
      -- but the spine is defined.
      deepErrorX :: HasCallStack => String -> a

      default deepErrorX :: (HasCallStack, Generic a, GDeepErrorX (Rep a)) => String -> a
      deepErrorX = (HasCallStack => String -> a) -> String -> a
    forall a. HasCallStack => (HasCallStack => a) -> a
    withFrozenCallStack ((HasCallStack => String -> a) -> String -> a)
    -> (HasCallStack => String -> a) -> String -> a
    forall a b. (a -> b) -> a -> b
    $ Rep a (ZonkAny 0) -> a
    forall a x. Generic a => Rep a x -> a
    forall x. Rep a x -> a
    to (Rep a (ZonkAny 0) -> a)
    -> (String -> Rep a (ZonkAny 0)) -> String -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Rep a (ZonkAny 0)
    forall a. HasCallStack => String -> Rep a a
    forall (f :: Type -> Type) a.
    (GDeepErrorX f, HasCallStack) =>
    String -> f a
    gDeepErrorX

      -- | Determines whether any of parts of a given construct contain undefined
      -- parts. Note that a negative answer does not mean its bit representation
      -- is fully defined. For example:
      --
      -- >>> m = Nothing :: Maybe Bool
      -- >>> hasUndefined m
      -- False
      -- >>> pack m
      -- 0b0.
      -- >>> hasUndefined (pack m)
      -- True
      --
      hasUndefined :: a -> Bool

      default hasUndefined :: (Generic a, GHasUndefined (Rep a)) => a -> Bool
      hasUndefined = Rep a (ZonkAny 1) -> Bool
    forall a. Rep a a -> Bool
    forall (f :: Type -> Type) a. GHasUndefined f => f a -> Bool
    gHasUndefined (Rep a (ZonkAny 1) -> Bool)
    -> (a -> Rep a (ZonkAny 1)) -> a -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Rep a (ZonkAny 1)
    forall x. a -> Rep a x
    forall a x. Generic a => a -> Rep a x
    from

      -- | Create a value where at the very least the spine is defined. For example:
      --
      -- >>> spined = ensureSpine (errorX "?" :: (Int, Int))
      -- >>> case spined of (_, _) -> 'a'
      -- 'a'
      -- >>> fmap (const 'b') (ensureSpine undefined :: Vec 3 Int)
      -- 'b' :> 'b' :> 'b' :> Nil
      -- >>> fmap (const 'c') (ensureSpine undefined :: RTree 2 Int)
      -- <<'c','c'>,<'c','c'>>
      --
      -- For users familiar with 'Clash.Sized.Vector.lazyV': this is the generalized
      -- version of it.
      ensureSpine :: a -> a

      default ensureSpine :: (Generic a, GEnsureSpine (Rep a)) => a -> a
      ensureSpine = Rep a (ZonkAny 2) -> a
    forall a x. Generic a => Rep a x -> a
    forall x. Rep a x -> a
    to (Rep a (ZonkAny 2) -> a) -> (a -> Rep a (ZonkAny 2)) -> a -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Rep a (ZonkAny 2) -> Rep a (ZonkAny 2)
    forall a. Rep a a -> Rep a a
    forall (f :: Type -> Type) a. GEnsureSpine f => f a -> f a
    gEnsureSpine (Rep a (ZonkAny 2) -> Rep a (ZonkAny 2))
    -> (a -> Rep a (ZonkAny 2)) -> a -> Rep a (ZonkAny 2)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Rep a (ZonkAny 2)
    forall x. a -> Rep a x
    forall a x. Generic a => a -> Rep a x
    from

      -- | Evaluate a value to NF. As opposed to 'NFData's
      -- 'rnf', it does not bubble up 'XException's.
      rnfX :: a -> ()

      default rnfX :: (Generic a, GNFDataX Zero (Rep a)) => a -> ()
      rnfX = RnfArgs Zero (ZonkAny 3) -> Rep a (ZonkAny 3) -> ()
    forall a. RnfArgs Zero a -> Rep a a -> ()
    forall arity (f :: Type -> Type) a.
    GNFDataX arity f =>
    RnfArgs arity a -> f a -> ()
    grnfX RnfArgs Zero (ZonkAny 3)
    forall a. RnfArgs Zero a
    RnfArgs0 (Rep a (ZonkAny 3) -> ()) -> (a -> Rep a (ZonkAny 3)) -> a -> ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Rep a (ZonkAny 3)
    forall x. a -> Rep a x
    forall a x. Generic a => a -> Rep a x
    from

    instance NFDataX ()

    instance NFDataX b => NFDataX (a -> b) where
      deepErrorX :: HasCallStack => String -> a -> b
    deepErrorX = b -> a -> b
    forall a. a -> a -> a
    forall (f :: Type -> Type) a. Applicative f => a -> f a
    pure (b -> a -> b) -> (String -> b) -> String -> a -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> b
    forall a. (NFDataX a, HasCallStack) => String -> a
    deepErrorX
      rnfX :: (a -> b) -> ()
    rnfX = (a -> b) -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: (a -> b) -> Bool
    hasUndefined = String -> (a -> b) -> Bool
    forall a. HasCallStack => String -> a
    error String
    "hasUndefined on Undefined (a -> b): Not Yet Implemented"
      ensureSpine :: (a -> b) -> a -> b
    ensureSpine = (a -> b) -> a -> b
    forall a. a -> a
    id

    instance NFDataX a => NFDataX (Down a) where
      deepErrorX :: HasCallStack => String -> Down a
    deepErrorX = a -> Down a
    forall a. a -> Down a
    Down (a -> Down a) -> (String -> a) -> String -> Down a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> a
    forall a. (NFDataX a, HasCallStack) => String -> a
    deepErrorX
      rnfX :: Down a -> ()
    rnfX d :: Down a
    d@(~(Down a
    x)) = if Either String (Down a) -> Bool
    forall a b. Either a b -> Bool
    isLeft (Down a -> Either String (Down a)
    forall a. a -> Either String a
    isX Down a
    d) then () else a -> ()
    forall a. NFDataX a => a -> ()
    rnfX a
    x
      hasUndefined :: Down a -> Bool
    hasUndefined d :: Down a
    d@(~(Down a
    x))= if Either String (Down a) -> Bool
    forall a b. Either a b -> Bool
    isLeft (Down a -> Either String (Down a)
    forall a. a -> Either String a
    isX Down a
    d) then Bool
    True else a -> Bool
    forall a. NFDataX a => a -> Bool
    hasUndefined a
    x
      ensureSpine :: Down a -> Down a
    ensureSpine ~(Down a
    x) = a -> Down a
    forall a. a -> Down a
    Down (a -> a
    forall a. NFDataX a => a -> a
    ensureSpine a
    x)

    instance NFDataX a => NFDataX (Infinite a) where
      deepErrorX :: HasCallStack => String -> Infinite a
    deepErrorX String
    msg = a -> Infinite a
    forall a. a -> Infinite a
    Inf.repeat (String -> a
    forall a. (NFDataX a, HasCallStack) => String -> a
    deepErrorX String
    msg)
      rnfX :: Infinite a -> ()
    rnfX d :: Infinite a
    d@(~(a
    x :< Infinite a
    xs)) =
        if Either String (Infinite a) -> Bool
    forall a b. Either a b -> Bool
    isLeft (Infinite a -> Either String (Infinite a)
    forall a. a -> Either String a
    isX Infinite a
    d) then
          ()
        else
          a -> ()
    forall a. NFDataX a => a -> ()
    rnfX a
    x () -> () -> ()
    forall a b. a -> b -> b
    `seq` Infinite a -> ()
    forall a. NFDataX a => a -> ()
    rnfX Infinite a
    xs
      hasUndefined :: Infinite a -> Bool
    hasUndefined d :: Infinite a
    d@(~(a
    x :< Infinite a
    xs)) =
        if Either String (Infinite a) -> Bool
    forall a b. Either a b -> Bool
    isLeft (Infinite a -> Either String (Infinite a)
    forall a. a -> Either String a
    isX Infinite a
    d) then
          Bool
    True
        else
          a -> Bool
    forall a. NFDataX a => a -> Bool
    hasUndefined a
    x Bool -> Bool -> Bool
    || Infinite a -> Bool
    forall a. NFDataX a => a -> Bool
    hasUndefined Infinite a
    xs

      ensureSpine :: Infinite a -> Infinite a
    ensureSpine ~(a
    x :< Infinite a
    xs) = a -> a
    forall a. NFDataX a => a -> a
    ensureSpine a
    x a -> Infinite a -> Infinite a
    forall a. a -> Infinite a -> Infinite a
    :< Infinite a -> Infinite a
    forall a. NFDataX a => a -> a
    ensureSpine Infinite a
    xs

    instance NFDataX Bool
    instance NFDataX Ordering
    instance NFDataX a => NFDataX [a]
    instance NFDataX a => NFDataX (NonEmpty a)
    instance (NFDataX a, NFDataX b) => NFDataX (Either a b)
    instance NFDataX a => NFDataX (Maybe a)
    -- | @since 1.8.2
    instance NFDataX (Proxy a)
    instance NFDataX a => NFDataX (Identity a)
    instance NFDataX a => NFDataX (Const a b)
    instance (NFDataX (f a), NFDataX (g a)) => NFDataX (Product f g a)
    instance (NFDataX (f a), NFDataX (g a)) => NFDataX (Sum f g a)
    instance (NFDataX (f (g a))) => NFDataX (Compose f g a)

    instance NFDataX Char where
      deepErrorX :: HasCallStack => String -> Char
    deepErrorX = String -> Char
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Char -> ()
    rnfX = Char -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Char -> Bool
    hasUndefined = Either String Char -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Char -> Bool)
    -> (Char -> Either String Char) -> Char -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Char -> Either String Char
    forall a. a -> Either String a
    isX
      ensureSpine :: Char -> Char
    ensureSpine = Char -> Char
    forall a. a -> a
    id

    instance NFDataX Double where
      deepErrorX :: HasCallStack => String -> Double
    deepErrorX = String -> Double
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Double -> ()
    rnfX = Double -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Double -> Bool
    hasUndefined = Either String Double -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Double -> Bool)
    -> (Double -> Either String Double) -> Double -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Either String Double
    forall a. a -> Either String a
    isX
      ensureSpine :: Double -> Double
    ensureSpine = Double -> Double
    forall a. a -> a
    id

    instance NFDataX Float where
      deepErrorX :: HasCallStack => String -> Float
    deepErrorX = String -> Float
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Float -> ()
    rnfX = Float -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Float -> Bool
    hasUndefined = Either String Float -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Float -> Bool)
    -> (Float -> Either String Float) -> Float -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Float -> Either String Float
    forall a. a -> Either String a
    isX
      ensureSpine :: Float -> Float
    ensureSpine = Float -> Float
    forall a. a -> a
    id

    instance NFDataX Int where
      deepErrorX :: HasCallStack => String -> Int
    deepErrorX = String -> Int
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Int -> ()
    rnfX = Int -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Int -> Bool
    hasUndefined = Either String Int -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Int -> Bool)
    -> (Int -> Either String Int) -> Int -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> Either String Int
    forall a. a -> Either String a
    isX
      ensureSpine :: Int -> Int
    ensureSpine = Int -> Int
    forall a. a -> a
    id

    instance NFDataX Int8 where
      deepErrorX :: HasCallStack => String -> Int8
    deepErrorX = String -> Int8
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Int8 -> ()
    rnfX = Int8 -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Int8 -> Bool
    hasUndefined = Either String Int8 -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Int8 -> Bool)
    -> (Int8 -> Either String Int8) -> Int8 -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int8 -> Either String Int8
    forall a. a -> Either String a
    isX
      ensureSpine :: Int8 -> Int8
    ensureSpine = Int8 -> Int8
    forall a. a -> a
    id

    instance NFDataX Int16 where
      deepErrorX :: HasCallStack => String -> Int16
    deepErrorX = String -> Int16
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Int16 -> ()
    rnfX = Int16 -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Int16 -> Bool
    hasUndefined = Either String Int16 -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Int16 -> Bool)
    -> (Int16 -> Either String Int16) -> Int16 -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int16 -> Either String Int16
    forall a. a -> Either String a
    isX
      ensureSpine :: Int16 -> Int16
    ensureSpine = Int16 -> Int16
    forall a. a -> a
    id

    instance NFDataX Int32 where
      deepErrorX :: HasCallStack => String -> Int32
    deepErrorX = String -> Int32
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Int32 -> ()
    rnfX = Int32 -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Int32 -> Bool
    hasUndefined = Either String Int32 -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Int32 -> Bool)
    -> (Int32 -> Either String Int32) -> Int32 -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int32 -> Either String Int32
    forall a. a -> Either String a
    isX
      ensureSpine :: Int32 -> Int32
    ensureSpine = Int32 -> Int32
    forall a. a -> a
    id

    instance NFDataX Int64 where
      deepErrorX :: HasCallStack => String -> Int64
    deepErrorX = String -> Int64
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Int64 -> ()
    rnfX = Int64 -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Int64 -> Bool
    hasUndefined = Either String Int64 -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Int64 -> Bool)
    -> (Int64 -> Either String Int64) -> Int64 -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> Either String Int64
    forall a. a -> Either String a
    isX
      ensureSpine :: Int64 -> Int64
    ensureSpine = Int64 -> Int64
    forall a. a -> a
    id

    instance NFDataX Integer where
      deepErrorX :: HasCallStack => String -> Integer
    deepErrorX = String -> Integer
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Integer -> ()
    rnfX = Integer -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Integer -> Bool
    hasUndefined = Either String Integer -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Integer -> Bool)
    -> (Integer -> Either String Integer) -> Integer -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> Either String Integer
    forall a. a -> Either String a
    isX
      ensureSpine :: Integer -> Integer
    ensureSpine = Integer -> Integer
    forall a. a -> a
    id

    instance NFDataX Natural where
      deepErrorX :: HasCallStack => String -> Natural
    deepErrorX = String -> Natural
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Natural -> ()
    rnfX = Natural -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Natural -> Bool
    hasUndefined = Either String Natural -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Natural -> Bool)
    -> (Natural -> Either String Natural) -> Natural -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Natural -> Either String Natural
    forall a. a -> Either String a
    isX
      ensureSpine :: Natural -> Natural
    ensureSpine = Natural -> Natural
    forall a. a -> a
    id

    instance NFDataX Word where
      deepErrorX :: HasCallStack => String -> Word
    deepErrorX = String -> Word
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Word -> ()
    rnfX = Word -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Word -> Bool
    hasUndefined = Either String Word -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Word -> Bool)
    -> (Word -> Either String Word) -> Word -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Word -> Either String Word
    forall a. a -> Either String a
    isX
      ensureSpine :: Word -> Word
    ensureSpine = Word -> Word
    forall a. a -> a
    id

    instance NFDataX Word8 where
      deepErrorX :: HasCallStack => String -> Word8
    deepErrorX = String -> Word8
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Word8 -> ()
    rnfX = Word8 -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Word8 -> Bool
    hasUndefined = Either String Word8 -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Word8 -> Bool)
    -> (Word8 -> Either String Word8) -> Word8 -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Word8 -> Either String Word8
    forall a. a -> Either String a
    isX
      ensureSpine :: Word8 -> Word8
    ensureSpine = Word8 -> Word8
    forall a. a -> a
    id

    instance NFDataX Word16 where
      deepErrorX :: HasCallStack => String -> Word16
    deepErrorX = String -> Word16
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Word16 -> ()
    rnfX = Word16 -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Word16 -> Bool
    hasUndefined = Either String Word16 -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Word16 -> Bool)
    -> (Word16 -> Either String Word16) -> Word16 -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Word16 -> Either String Word16
    forall a. a -> Either String a
    isX
      ensureSpine :: Word16 -> Word16
    ensureSpine = Word16 -> Word16
    forall a. a -> a
    id

    instance NFDataX Word32 where
      deepErrorX :: HasCallStack => String -> Word32
    deepErrorX = String -> Word32
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Word32 -> ()
    rnfX = Word32 -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Word32 -> Bool
    hasUndefined = Either String Word32 -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Word32 -> Bool)
    -> (Word32 -> Either String Word32) -> Word32 -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Word32 -> Either String Word32
    forall a. a -> Either String a
    isX
      ensureSpine :: Word32 -> Word32
    ensureSpine = Word32 -> Word32
    forall a. a -> a
    id

    instance NFDataX Word64 where
      deepErrorX :: HasCallStack => String -> Word64
    deepErrorX = String -> Word64
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Word64 -> ()
    rnfX = Word64 -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Word64 -> Bool
    hasUndefined = Either String Word64 -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Word64 -> Bool)
    -> (Word64 -> Either String Word64) -> Word64 -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Word64 -> Either String Word64
    forall a. a -> Either String a
    isX
      ensureSpine :: Word64 -> Word64
    ensureSpine = Word64 -> Word64
    forall a. a -> a
    id

    instance NFDataX CUShort where
      deepErrorX :: HasCallStack => String -> CUShort
    deepErrorX = String -> CUShort
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: CUShort -> ()
    rnfX = CUShort -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: CUShort -> Bool
    hasUndefined = Either String CUShort -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String CUShort -> Bool)
    -> (CUShort -> Either String CUShort) -> CUShort -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CUShort -> Either String CUShort
    forall a. a -> Either String a
    isX
      ensureSpine :: CUShort -> CUShort
    ensureSpine = CUShort -> CUShort
    forall a. a -> a
    id

    instance NFDataX Half where
      deepErrorX :: HasCallStack => String -> Half
    deepErrorX = String -> Half
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Half -> ()
    rnfX = Half -> ()
    forall a. a -> ()
    rwhnfX
      hasUndefined :: Half -> Bool
    hasUndefined = Either String Half -> Bool
    forall a b. Either a b -> Bool
    isLeft (Either String Half -> Bool)
    -> (Half -> Either String Half) -> Half -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Half -> Either String Half
    forall a. a -> Either String a
    isX
      ensureSpine :: Half -> Half
    ensureSpine = Half -> Half
    forall a. a -> a
    id

    instance NFDataX a => NFDataX (Seq a) where
      deepErrorX :: HasCallStack => String -> Seq a
    deepErrorX = String -> Seq a
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Seq a -> ()
    rnfX Seq a
    s =
        if Either String (Seq a) -> Bool
    forall a b. Either a b -> Bool
    isLeft (Seq a -> Either String (Seq a)
    forall a. a -> Either String a
    isX Seq a
    s) then () else Seq a -> ()
    forall a. NFDataX a => Seq a -> ()
    go Seq a
    s
       where
        go :: Seq a -> ()
    go Seq a
    Empty = ()
        go (a
    x :<| Seq a
    xs) = a -> ()
    forall a. NFDataX a => a -> ()
    rnfX a
    x () -> () -> ()
    forall a b. a -> b -> b
    `seq` Seq a -> ()
    go Seq a
    xs
      ensureSpine :: Seq a -> Seq a
    ensureSpine = Seq a -> Seq a
    forall a. a -> a
    id

      hasUndefined :: Seq a -> Bool
    hasUndefined Seq a
    s =
        if Either String (Seq a) -> Bool
    forall a b. Either a b -> Bool
    isLeft (Seq a -> Either String (Seq a)
    forall a. a -> Either String a
    isX Seq a
    s) then Bool
    True else Seq a -> Bool
    forall a. NFDataX a => Seq a -> Bool
    go Seq a
    s
       where
        go :: Seq a -> Bool
    go Seq a
    Empty = Bool
    False
        go (a
    x :<| Seq a
    xs) = a -> Bool
    forall a. NFDataX a => a -> Bool
    hasUndefined a
    x Bool -> Bool -> Bool
    || Seq a -> Bool
    forall a. NFDataX a => a -> Bool
    hasUndefined Seq a
    xs

    instance NFDataX a => NFDataX (Ratio a) where
      deepErrorX :: HasCallStack => String -> Ratio a
    deepErrorX = String -> Ratio a
    forall a. HasCallStack => String -> a
    errorX
      rnfX :: Ratio a -> ()
    rnfX Ratio a
    r = a -> ()
    forall a. NFDataX a => a -> ()
    rnfX (Ratio a -> a
    forall a. Ratio a -> a
    numerator Ratio a
    r) () -> () -> ()
    forall a b. a -> b -> b
    `seq` a -> ()
    forall a. NFDataX a => a -> ()
    rnfX (Ratio a -> a
    forall a. Ratio a -> a
    denominator Ratio a
    r)
      hasUndefined :: Ratio a -> Bool
    hasUndefined Ratio a
    r = Either String a -> Bool
    forall a b. Either a b -> Bool
    isLeft (a -> Either String a
    forall a. a -> Either String a
    isX (Ratio a -> a
    forall a. Ratio a -> a
    numerator Ratio a
    r)) Bool -> Bool -> Bool
    || Either String a -> Bool
    forall a b. Either a b -> Bool
    isLeft (a -> Either String a
    forall a. a -> Either String a
    isX (Ratio a -> a
    forall a. Ratio a -> a
    denominator Ratio a
    r))
      ensureSpine :: Ratio a -> Ratio a
    ensureSpine = Ratio a -> Ratio a
    forall a. a -> a
    id

    instance NFDataX a => NFDataX (Complex a) where
      deepErrorX :: HasCallStack => String -> Complex a
    deepErrorX = String -> Complex a
    forall a. HasCallStack => String -> a
    errorX

    instance (NFDataX a, NFDataX b) => NFDataX (SG.Arg a b)
    instance NFDataX (SG.All)
    instance NFDataX (SG.Any)
    instance NFDataX a => NFDataX (SG.Dual a)
    instance NFDataX a => NFDataX (SG.Endo a)
    instance NFDataX a => NFDataX (SG.First a)
    instance NFDataX a => NFDataX (SG.Last a)
    instance NFDataX a => NFDataX (SG.Max a)
    instance NFDataX a => NFDataX (SG.Min a)
    instance NFDataX a => NFDataX (SG.Product a)
    instance NFDataX a => NFDataX (SG.Sum a)
    instance NFDataX a => NFDataX (M.First a)
    instance NFDataX a => NFDataX (M.Last a)

    -- Sg.Option will be removed in 9.2. We can't locally disable deprecation
    -- warnings (i.e., for this instance only) so we're prematurely removing it
    -- instead.
    #if __GLASGOW_HASKELL__ < 900
    instance NFDataX a => NFDataX (SG.Option a)
    #endif

    -- | __NB__: The documentation only shows instances up to /3/-tuples. By
    -- default, instances up to and including /12/-tuples will exist. If the flag
    -- @large-tuples@ is set instances up to the GHC imposed limit will exist. The
    -- GHC imposed limit is either 62 or 64 depending on the GHC version.
    mkShowXTupleInstances [2..maxTupleSize]

    -- | __NB__: The documentation only shows instances up to /3/-tuples. By
    -- default, instances up to and including /12/-tuples will exist. If the flag
    -- @large-tuples@ is set instances up to the GHC imposed limit will exist. The
    -- GHC imposed limit is either 62 or 64 depending on the GHC version.
    mkNFDataXTupleInstances [2..maxTupleSize]

    -- | Call to 'errorX' with default string
    undefined :: HasCallStack => a
    undefined :: forall a. HasCallStack => a
    undefined = String -> a
    forall a. HasCallStack => String -> a
    errorX String
    "undefined"

    -- | Same as 'Data.Maybe.fromJust', but returns a bottom/undefined value that
    -- other Clash constructs are aware of.
    fromJustX :: (HasCallStack, NFDataX a) => Maybe a -> a
    fromJustX :: forall a. (HasCallStack, NFDataX a) => Maybe a -> a
    fromJustX Maybe a
    Nothing = String -> a
    forall a. (NFDataX a, HasCallStack) => String -> a
    deepErrorX String
    "fromJustX: Nothing"
    fromJustX (Just a
    a) = a
    a