    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE FlexibleInstances     #-}
    {-# LANGUAGE ScopedTypeVariables   #-}
    {-# LANGUAGE ConstraintKinds       #-}
    {-# LANGUAGE CPP                   #-}
    {-# LANGUAGE MagicHash             #-}
    {-# LANGUAGE UndecidableInstances  #-}
    {-# LANGUAGE TypeOperators         #-}
    -- |
    -- Module      : Basement.From
    -- License     : BSD-style
    -- Maintainer  : Haskell Foundation
    --
    -- Flexible Type convertion
    --
    -- From is multi parameter type class that allow converting
    -- from a to b.
    --
    -- Only type that are valid to convert to another type
    -- should be From instance; otherwise TryFrom should be used.
    --
    -- Into (resp TryInto) allows the contrary instances to be able
    -- to specify the destination type before the source. This is
    -- practical with TypeApplication
    module Basement.From
        ( From(..)
        , Into
        , TryFrom(..)
        , TryInto
        , into
        , tryInto
        ) where

    import           Basement.Compat.Base

    -- basic instances
    import           GHC.Types
    import           GHC.Prim hiding (word64ToWord#)
    import qualified GHC.Prim
    import           GHC.Int
    import           GHC.Word
    import           Basement.Numerical.Number
    import           Basement.Numerical.Conversion
    import qualified Basement.Block as Block
    import qualified Basement.BoxedArray as BoxArray
    import           Basement.Cast (cast)
    import qualified Basement.UArray as UArray
    import qualified Basement.String as String
    import qualified Basement.Types.AsciiString as AsciiString
    import           Basement.Types.Word128 (Word128(..))
    import           Basement.Types.Word256 (Word256(..))
    import qualified Basement.Types.Word128 as Word128
    import qualified Basement.Types.Word256 as Word256
    import           Basement.These
    import           Basement.PrimType (PrimType, PrimSize)
    import           Basement.Types.OffsetSize
    import           Basement.Compat.Natural
    import           Basement.Compat.Primitive
    import qualified Prelude (fromIntegral)

    -- nat instances
    #if __GLASGOW_HASKELL__ >= 800
    import           Basement.Nat
    import qualified Basement.Sized.Block as BlockN
    import           Basement.Bounded
    #endif

    -- | Class of things that can be converted from a to b.
    --
    -- In a valid instance, the source should be always representable by the destination,
    -- otherwise the instance should be using 'TryFrom'
    class From a b where
        from :: a -> b

    type Into b a = From a b

    -- | Same as from but reverse the type variable so that the destination type can be specified first
    --
    -- e.g. converting:
    --
    -- from @_ @Word (10 :: Int)
    --
    -- into @Word (10 :: Int)
    --
    into :: Into b a => a -> b
    into :: forall b a. Into b a => a -> b
    into = a -> b
    forall a b. From a b => a -> b
    from

    -- | Class of things that can mostly be converted from a to b, but with possible error cases.
    class TryFrom a b where
        tryFrom :: a -> Maybe b

    type TryInto b a = TryFrom a b

    -- | same as tryFrom but reversed
    tryInto :: TryInto b a => a -> Maybe b
    tryInto :: forall b a. TryInto b a => a -> Maybe b
    tryInto = a -> Maybe b
    forall a b. TryFrom a b => a -> Maybe b
    tryFrom

    instance From a a where
        from :: a -> a
    from = a -> a
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id

    instance IsNatural n => From n Natural where
        from :: n -> Natural
    from = n -> Natural
    forall n. IsNatural n => n -> Natural
    toNatural
    instance IsIntegral n => From n Integer where
        from :: n -> Integer
    from = n -> Integer
    forall n. IsIntegral n => n -> Integer
    toInteger

    instance From Int8 Int16 where
        from :: Int8 -> Int16
    from (I8# Int8#
    i) = Int16# -> Int16
    I16# (Int8# -> Int16#
    int8ToInt16# Int8#
    i)
    instance From Int8 Int32 where
        from :: Int8 -> Int32
    from (I8# Int8#
    i) = Int32# -> Int32
    I32# (Int8# -> Int32#
    int8ToInt32# Int8#
    i)
    instance From Int8 Int64 where
        from :: Int8 -> Int64
    from (I8# Int8#
    i) = Int -> Int64
    intToInt64 (Int# -> Int
    I# (Int8# -> Int#
    int8ToInt# Int8#
    i))
    instance From Int8 Int where
        from :: Int8 -> Int
    from (I8# Int8#
    i) = Int# -> Int
    I# (Int8# -> Int#
    int8ToInt# Int8#
    i)

    instance From Int16 Int32 where
        from :: Int16 -> Int32
    from (I16# Int16#
    i) = Int32# -> Int32
    I32# (Int16# -> Int32#
    int16ToInt32# Int16#
    i)
    instance From Int16 Int64 where
        from :: Int16 -> Int64
    from (I16# Int16#
    i) = Int -> Int64
    intToInt64 (Int# -> Int
    I# (Int16# -> Int#
    int16ToInt# Int16#
    i))
    instance From Int16 Int where
        from :: Int16 -> Int
    from (I16# Int16#
    i) = Int# -> Int
    I# (Int16# -> Int#
    int16ToInt# Int16#
    i)

    instance From Int32 Int64 where
        from :: Int32 -> Int64
    from (I32# Int32#
    i) = Int -> Int64
    intToInt64 (Int# -> Int
    I# (Int32# -> Int#
    int32ToInt# Int32#
    i))
    instance From Int32 Int where
        from :: Int32 -> Int
    from (I32# Int32#
    i) = Int# -> Int
    I# (Int32# -> Int#
    int32ToInt# Int32#
    i)

    instance From Int Int64 where
        from :: Int -> Int64
    from = Int -> Int64
    intToInt64

    instance From Word8 Word16 where
        from :: Word8 -> Word16
    from (W8# Word8#
    i) = Word16# -> Word16
    W16# (Word8# -> Word16#
    word8ToWord16# Word8#
    i)
    instance From Word8 Word32 where
        from :: Word8 -> Word32
    from (W8# Word8#
    i) = Word32# -> Word32
    W32# (Word8# -> Word32#
    word8ToWord32# Word8#
    i)
    instance From Word8 Word64 where
        from :: Word8 -> Word64
    from (W8# Word8#
    i) = Word -> Word64
    wordToWord64 (Word# -> Word
    W# (Word8# -> Word#
    word8ToWord# Word8#
    i))
    instance From Word8 Word128 where
        from :: Word8 -> Word128
    from (W8# Word8#
    i) = Word64 -> Word64 -> Word128
    Word128 Word64
    0 (Word -> Word64
    wordToWord64 (Word -> Word64) -> Word -> Word64
    forall a b. (a -> b) -> a -> b
    $ Word# -> Word
    W# (Word8# -> Word#
    word8ToWord# Word8#
    i))
    instance From Word8 Word256 where
        from :: Word8 -> Word256
    from (W8# Word8#
    i) = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    0 Word64
    0 (Word -> Word64
    wordToWord64 (Word -> Word64) -> Word -> Word64
    forall a b. (a -> b) -> a -> b
    $ Word# -> Word
    W# (Word8# -> Word#
    word8ToWord# Word8#
    i))
    instance From Word8 Word where
        from :: Word8 -> Word
    from (W8# Word8#
    i) = Word# -> Word
    W# (Word8# -> Word#
    word8ToWord# Word8#
    i)
    instance From Word8 Int16 where
        from :: Word8 -> Int16
    from (W8# Word8#
    w) = Int16# -> Int16
    I16# (Int# -> Int16#
    intToInt16# (Word# -> Int#
    word2Int# (Word8# -> Word#
    word8ToWord# Word8#
    w)))
    instance From Word8 Int32 where
        from :: Word8 -> Int32
    from (W8# Word8#
    w) = Int32# -> Int32
    I32# (Int# -> Int32#
    intToInt32# (Word# -> Int#
    word2Int# (Word8# -> Word#
    word8ToWord# Word8#
    w)))
    instance From Word8 Int64 where
        from :: Word8 -> Int64
    from (W8# Word8#
    w) = Int -> Int64
    intToInt64 (Int# -> Int
    I# (Word# -> Int#
    word2Int# (Word8# -> Word#
    word8ToWord# Word8#
    w)))
    instance From Word8 Int where
        from :: Word8 -> Int
    from (W8# Word8#
    w) = Int# -> Int
    I# (Word# -> Int#
    word2Int# (Word8# -> Word#
    word8ToWord# Word8#
    w))

    instance From Word16 Word32 where
        from :: Word16 -> Word32
    from (W16# Word16#
    i) = Word32# -> Word32
    W32# (Word16# -> Word32#
    word16ToWord32# Word16#
    i)
    instance From Word16 Word64 where
        from :: Word16 -> Word64
    from (W16# Word16#
    i) = Word -> Word64
    wordToWord64 (Word# -> Word
    W# (Word16# -> Word#
    word16ToWord# Word16#
    i))
    instance From Word16 Word128 where
        from :: Word16 -> Word128
    from (W16# Word16#
    i) = Word64 -> Word64 -> Word128
    Word128 Word64
    0 (Word -> Word64
    wordToWord64 (Word -> Word64) -> Word -> Word64
    forall a b. (a -> b) -> a -> b
    $ Word# -> Word
    W# (Word16# -> Word#
    word16ToWord# Word16#
    i))
    instance From Word16 Word256 where
        from :: Word16 -> Word256
    from (W16# Word16#
    i) = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    0 Word64
    0 (Word -> Word64
    wordToWord64 (Word -> Word64) -> Word -> Word64
    forall a b. (a -> b) -> a -> b
    $ Word# -> Word
    W# (Word16# -> Word#
    word16ToWord# Word16#
    i))
    instance From Word16 Word where
        from :: Word16 -> Word
    from (W16# Word16#
    i) = Word# -> Word
    W# (Word16# -> Word#
    word16ToWord# Word16#
    i)
    instance From Word16 Int32 where
        from :: Word16 -> Int32
    from (W16# Word16#
    w) = Int32# -> Int32
    I32# (Int# -> Int32#
    intToInt32# (Word# -> Int#
    word2Int# (Word16# -> Word#
    word16ToWord# Word16#
    w)))
    instance From Word16 Int64 where
        from :: Word16 -> Int64
    from (W16# Word16#
    w) = Int -> Int64
    intToInt64 (Int# -> Int
    I# (Word# -> Int#
    word2Int# (Word16# -> Word#
    word16ToWord# Word16#
    w)))
    instance From Word16 Int where
        from :: Word16 -> Int
    from (W16# Word16#
    w) = Int# -> Int
    I# (Word# -> Int#
    word2Int# (Word16# -> Word#
    word16ToWord# Word16#
    w))

    instance From Word32 Word64 where
        from :: Word32 -> Word64
    from (W32# Word32#
    i) = Word -> Word64
    wordToWord64 (Word# -> Word
    W# (Word32# -> Word#
    word32ToWord# Word32#
    i))
    instance From Word32 Word128 where
        from :: Word32 -> Word128
    from (W32# Word32#
    i) = Word64 -> Word64 -> Word128
    Word128 Word64
    0 (Word -> Word64
    wordToWord64 (Word -> Word64) -> Word -> Word64
    forall a b. (a -> b) -> a -> b
    $ Word# -> Word
    W# (Word32# -> Word#
    word32ToWord# Word32#
    i))
    instance From Word32 Word256 where
        from :: Word32 -> Word256
    from (W32# Word32#
    i) = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    0 Word64
    0 (Word -> Word64
    wordToWord64 (Word -> Word64) -> Word -> Word64
    forall a b. (a -> b) -> a -> b
    $ Word# -> Word
    W# (Word32# -> Word#
    word32ToWord# Word32#
    i))
    instance From Word32 Word where
        from :: Word32 -> Word
    from (W32# Word32#
    i) = Word# -> Word
    W# (Word32# -> Word#
    word32ToWord# Word32#
    i)
    instance From Word32 Int64 where
        from :: Word32 -> Int64
    from (W32# Word32#
    w) = Int -> Int64
    intToInt64 (Int# -> Int
    I# (Word# -> Int#
    word2Int# (Word32# -> Word#
    word32ToWord# Word32#
    w)))
    instance From Word32 Int where
        from :: Word32 -> Int
    from (W32# Word32#
    w) = Int# -> Int
    I# (Word# -> Int#
    word2Int# (Word32# -> Word#
    word32ToWord# Word32#
    w))

    instance From Word64 Word128 where
        from :: Word64 -> Word128
    from Word64
    w = Word64 -> Word64 -> Word128
    Word128 Word64
    0 Word64
    w
    instance From Word64 Word256 where
        from :: Word64 -> Word256
    from Word64
    w = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    0 Word64
    0 Word64
    w

    instance From Word Word64 where
        from :: Word -> Word64
    from = Word -> Word64
    wordToWord64

    -- Simple prelude types
    instance From (Maybe a) (Either () a) where
        from :: Maybe a -> Either () a
    from (Just a
    x) = a -> Either () a
    forall a b. b -> Either a b
    Right a
    x
        from Maybe a
    Nothing  = () -> Either () a
    forall a b. a -> Either a b
    Left ()

    -- basic basement types
    instance From (CountOf ty) Int where
        from :: CountOf ty -> Int
    from (CountOf Int
    n) = Int
    n
    instance From (CountOf ty) Word where
        -- here it is ok to cast the underlying `Int` held by `CountOf` to a `Word`
        -- as the `Int` should never hold a negative value.
        from :: CountOf ty -> Word
    from (CountOf Int
    n) = Int -> Word
    forall source destination.
    Cast source destination =>
    source -> destination
    cast Int
    n
    instance From Word (Offset ty) where
        from :: Word -> Offset ty
    from Word
    w = Int -> Offset ty
    forall ty. Int -> Offset ty
    Offset (Word -> Int
    forall source destination.
    Cast source destination =>
    source -> destination
    cast Word
    w)
    instance TryFrom Int (Offset ty) where
        tryFrom :: Int -> Maybe (Offset ty)
    tryFrom Int
    i
            | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0     = Maybe (Offset ty)
    forall a. Maybe a
    Nothing
            | Bool
    otherwise = Offset ty -> Maybe (Offset ty)
    forall a. a -> Maybe a
    Just (Int -> Offset ty
    forall ty. Int -> Offset ty
    Offset Int
    i)
    instance TryFrom Int (CountOf ty) where
        tryFrom :: Int -> Maybe (CountOf ty)
    tryFrom Int
    i
            | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0     = Maybe (CountOf ty)
    forall a. Maybe a
    Nothing
            | Bool
    otherwise = CountOf ty -> Maybe (CountOf ty)
    forall a. a -> Maybe a
    Just (Int -> CountOf ty
    forall ty. Int -> CountOf ty
    CountOf Int
    i)
    instance From Word (CountOf ty) where
        from :: Word -> CountOf ty
    from Word
    w = Int -> CountOf ty
    forall ty. Int -> CountOf ty
    CountOf (Word -> Int
    forall source destination.
    Cast source destination =>
    source -> destination
    cast Word
    w)

    instance From (Either a b) (These a b) where
        from :: Either a b -> These a b
    from (Left a
    a) = a -> These a b
    forall a b. a -> These a b
    This a
    a
        from (Right b
    b) = b -> These a b
    forall a b. b -> These a b
    That b
    b

    instance From Word128 Word256 where
        from :: Word128 -> Word256
    from (Word128 Word64
    a Word64
    b) = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    0 Word64
    a Word64
    b

    -- basement instances

    -- uarrays
    instance PrimType ty => From (Block.Block ty) (UArray.UArray ty) where
        from :: Block ty -> UArray ty
    from = Block ty -> UArray ty
    forall ty. PrimType ty => Block ty -> UArray ty
    UArray.fromBlock
    instance PrimType ty => From (BoxArray.Array ty) (UArray.UArray ty) where
        from :: Array ty -> UArray ty
    from = (ty -> ty) -> Array ty -> UArray ty
    forall b a. PrimType b => (a -> b) -> Array a -> UArray b
    BoxArray.mapToUnboxed ty -> ty
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id

    -- blocks
    instance PrimType ty => From (UArray.UArray ty) (Block.Block ty) where
        from :: UArray ty -> Block ty
    from = UArray ty -> Block ty
    forall ty. PrimType ty => UArray ty -> Block ty
    UArray.toBlock
    instance PrimType ty => From (BoxArray.Array ty) (Block.Block ty) where
        from :: Array ty -> Block ty
    from = UArray ty -> Block ty
    forall ty. PrimType ty => UArray ty -> Block ty
    UArray.toBlock (UArray ty -> Block ty)
    -> (Array ty -> UArray ty) -> Array ty -> Block ty
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (ty -> ty) -> Array ty -> UArray ty
    forall b a. PrimType b => (a -> b) -> Array a -> UArray b
    BoxArray.mapToUnboxed ty -> ty
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id

    -- boxed array
    instance PrimType ty => From (UArray.UArray ty) (BoxArray.Array ty) where
        from :: UArray ty -> Array ty
    from = (ty -> ty) -> UArray ty -> Array ty
    forall a b. PrimType a => (a -> b) -> UArray a -> Array b
    BoxArray.mapFromUnboxed ty -> ty
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id

    instance From String.String (UArray.UArray Word8) where
        from :: String -> UArray Word8
    from = Encoding -> String -> UArray Word8
    String.toBytes Encoding
    String.UTF8

    instance From AsciiString.AsciiString String.String where
        from :: AsciiString -> String
    from = UArray Word8 -> String
    String.fromBytesUnsafe (UArray Word8 -> String)
    -> (AsciiString -> UArray Word8) -> AsciiString -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . UArray Char7 -> UArray Word8
    forall a b. (PrimType a, PrimType b) => UArray a -> UArray b
    UArray.unsafeRecast (UArray Char7 -> UArray Word8)
    -> (AsciiString -> UArray Char7) -> AsciiString -> UArray Word8
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . AsciiString -> UArray Char7
    AsciiString.toBytes
    instance From AsciiString.AsciiString (UArray.UArray Word8) where
        from :: AsciiString -> UArray Word8
    from = UArray Char7 -> UArray Word8
    forall a b. (PrimType a, PrimType b) => UArray a -> UArray b
    UArray.unsafeRecast (UArray Char7 -> UArray Word8)
    -> (AsciiString -> UArray Char7) -> AsciiString -> UArray Word8
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . AsciiString -> UArray Char7
    AsciiString.toBytes

    instance TryFrom (UArray.UArray Word8) String.String where
        tryFrom :: UArray Word8 -> Maybe String
    tryFrom UArray Word8
    arr = case Encoding
    -> UArray Word8 -> (String, Maybe ValidationFailure, UArray Word8)
    String.fromBytes Encoding
    String.UTF8 UArray Word8
    arr of
                        (String
    s, Maybe ValidationFailure
    Nothing, UArray Word8
    _) -> String -> Maybe String
    forall a. a -> Maybe a
    Just String
    s
                        (String
    _, Just ValidationFailure
    _, UArray Word8
    _)  -> Maybe String
    forall a. Maybe a
    Nothing

    #if __GLASGOW_HASKELL__ >= 800
    instance From (BlockN.BlockN n ty) (Block.Block ty) where
        from :: BlockN n ty -> Block ty
    from = BlockN n ty -> Block ty
    forall (n :: Natural) ty. BlockN n ty -> Block ty
    BlockN.toBlock
    instance (PrimType a, PrimType b, KnownNat n, KnownNat m, ((PrimSize b) Basement.Nat.* m) ~ ((PrimSize a) Basement.Nat.* n))
          => From (BlockN.BlockN n a) (BlockN.BlockN m b) where
        from :: BlockN n a -> BlockN m b
    from = BlockN n a -> BlockN m b
    forall (n :: Natural) (m :: Natural) a b.
    (PrimType a, PrimType b, KnownNat n, KnownNat m,
     (PrimSize b * m) ~ (PrimSize a * n)) =>
    BlockN n a -> BlockN m b
    BlockN.cast
    instance (NatWithinBound Int n, PrimType ty) => From (BlockN.BlockN n ty) (UArray.UArray ty) where
        from :: BlockN n ty -> UArray ty
    from = Block ty -> UArray ty
    forall ty. PrimType ty => Block ty -> UArray ty
    UArray.fromBlock (Block ty -> UArray ty)
    -> (BlockN n ty -> Block ty) -> BlockN n ty -> UArray ty
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . BlockN n ty -> Block ty
    forall (n :: Natural) ty. BlockN n ty -> Block ty
    BlockN.toBlock
    instance (NatWithinBound Int n, PrimType ty) => From (BlockN.BlockN n ty) (BoxArray.Array ty) where
        from :: BlockN n ty -> Array ty
    from = (ty -> ty) -> UArray ty -> Array ty
    forall a b. PrimType a => (a -> b) -> UArray a -> Array b
    BoxArray.mapFromUnboxed ty -> ty
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id (UArray ty -> Array ty)
    -> (BlockN n ty -> UArray ty) -> BlockN n ty -> Array ty
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Block ty -> UArray ty
    forall ty. PrimType ty => Block ty -> UArray ty
    UArray.fromBlock (Block ty -> UArray ty)
    -> (BlockN n ty -> Block ty) -> BlockN n ty -> UArray ty
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . BlockN n ty -> Block ty
    forall (n :: Natural) ty. BlockN n ty -> Block ty
    BlockN.toBlock

    instance (NatWithinBound (CountOf ty) n, KnownNat n, PrimType ty)
          => TryFrom (Block.Block ty) (BlockN.BlockN n ty) where
        tryFrom :: Block ty -> Maybe (BlockN n ty)
    tryFrom = Block ty -> Maybe (BlockN n ty)
    forall (n :: Natural) ty.
    (PrimType ty, KnownNat n, Countable ty n) =>
    Block ty -> Maybe (BlockN n ty)
    BlockN.toBlockN
    instance (NatWithinBound (CountOf ty) n, KnownNat n, PrimType ty)
          => TryFrom (UArray.UArray ty) (BlockN.BlockN n ty) where
        tryFrom :: UArray ty -> Maybe (BlockN n ty)
    tryFrom = Block ty -> Maybe (BlockN n ty)
    forall (n :: Natural) ty.
    (PrimType ty, KnownNat n, Countable ty n) =>
    Block ty -> Maybe (BlockN n ty)
    BlockN.toBlockN (Block ty -> Maybe (BlockN n ty))
    -> (UArray ty -> Block ty) -> UArray ty -> Maybe (BlockN n ty)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . UArray ty -> Block ty
    forall ty. PrimType ty => UArray ty -> Block ty
    UArray.toBlock
    instance (NatWithinBound (CountOf ty) n, KnownNat n, PrimType ty)
          => TryFrom (BoxArray.Array ty) (BlockN.BlockN n ty) where
        tryFrom :: Array ty -> Maybe (BlockN n ty)
    tryFrom = Block ty -> Maybe (BlockN n ty)
    forall (n :: Natural) ty.
    (PrimType ty, KnownNat n, Countable ty n) =>
    Block ty -> Maybe (BlockN n ty)
    BlockN.toBlockN (Block ty -> Maybe (BlockN n ty))
    -> (Array ty -> Block ty) -> Array ty -> Maybe (BlockN n ty)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . UArray ty -> Block ty
    forall ty. PrimType ty => UArray ty -> Block ty
    UArray.toBlock (UArray ty -> Block ty)
    -> (Array ty -> UArray ty) -> Array ty -> Block ty
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (ty -> ty) -> Array ty -> UArray ty
    forall b a. PrimType b => (a -> b) -> Array a -> UArray b
    BoxArray.mapToUnboxed ty -> ty
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id

    instance (KnownNat n, NatWithinBound Word8 n) => From (Zn64 n) Word8 where
        from :: Zn64 n -> Word8
    from = Word64 -> Word8
    narrow (Word64 -> Word8) -> (Zn64 n -> Word64) -> Zn64 n -> Word8
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Zn64 n -> Word64
    forall (n :: Natural). Zn64 n -> Word64
    unZn64 where narrow :: Word64 -> Word8
    narrow (W64# Word64#
    w) = Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# (Word64# -> Word#
    word64ToWord# Word64#
    w))
    instance (KnownNat n, NatWithinBound Word16 n) => From (Zn64 n) Word16 where
        from :: Zn64 n -> Word16
    from = Word64 -> Word16
    narrow (Word64 -> Word16) -> (Zn64 n -> Word64) -> Zn64 n -> Word16
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Zn64 n -> Word64
    forall (n :: Natural). Zn64 n -> Word64
    unZn64 where narrow :: Word64 -> Word16
    narrow (W64# Word64#
    w) = Word16# -> Word16
    W16# (Word# -> Word16#
    wordToWord16# (Word64# -> Word#
    word64ToWord# Word64#
    w))
    instance (KnownNat n, NatWithinBound Word32 n) => From (Zn64 n) Word32 where
        from :: Zn64 n -> Word32
    from = Word64 -> Word32
    narrow (Word64 -> Word32) -> (Zn64 n -> Word64) -> Zn64 n -> Word32
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Zn64 n -> Word64
    forall (n :: Natural). Zn64 n -> Word64
    unZn64 where narrow :: Word64 -> Word32
    narrow (W64# Word64#
    w) = Word32# -> Word32
    W32# (Word# -> Word32#
    wordToWord32# (Word64# -> Word#
    word64ToWord# Word64#
    w))
    instance From (Zn64 n) Word64 where
        from :: Zn64 n -> Word64
    from = Zn64 n -> Word64
    forall (n :: Natural). Zn64 n -> Word64
    unZn64
    instance From (Zn64 n) Word128 where
        from :: Zn64 n -> Word128
    from = Word64 -> Word128
    forall a b. From a b => a -> b
    from (Word64 -> Word128) -> (Zn64 n -> Word64) -> Zn64 n -> Word128
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Zn64 n -> Word64
    forall (n :: Natural). Zn64 n -> Word64
    unZn64
    instance From (Zn64 n) Word256 where
        from :: Zn64 n -> Word256
    from = Word64 -> Word256
    forall a b. From a b => a -> b
    from (Word64 -> Word256) -> (Zn64 n -> Word64) -> Zn64 n -> Word256
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Zn64 n -> Word64
    forall (n :: Natural). Zn64 n -> Word64
    unZn64

    instance (KnownNat n, NatWithinBound Word8 n) => From (Zn n) Word8 where
        from :: Zn n -> Word8
    from = Word64 -> Word8
    narrow (Word64 -> Word8) -> (Zn n -> Word64) -> Zn n -> Word8
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Natural -> Word64
    naturalToWord64 (Natural -> Word64) -> (Zn n -> Natural) -> Zn n -> Word64
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Zn n -> Natural
    forall (n :: Natural). Zn n -> Natural
    unZn where narrow :: Word64 -> Word8
    narrow (W64# Word64#
    w) = Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# (Word64# -> Word#
    word64ToWord# Word64#
    w))
    instance (KnownNat n, NatWithinBound Word16 n) => From (Zn n) Word16 where
        from :: Zn n -> Word16
    from = Word64 -> Word16
    narrow (Word64 -> Word16) -> (Zn n -> Word64) -> Zn n -> Word16
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Natural -> Word64
    naturalToWord64 (Natural -> Word64) -> (Zn n -> Natural) -> Zn n -> Word64
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Zn n -> Natural
    forall (n :: Natural). Zn n -> Natural
    unZn where narrow :: Word64 -> Word16
    narrow (W64# Word64#
    w) = Word16# -> Word16
    W16# (Word# -> Word16#
    wordToWord16# (Word64# -> Word#
    word64ToWord# Word64#
    w))
    instance (KnownNat n, NatWithinBound Word32 n) => From (Zn n) Word32 where
        from :: Zn n -> Word32
    from = Word64 -> Word32
    narrow (Word64 -> Word32) -> (Zn n -> Word64) -> Zn n -> Word32
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Natural -> Word64
    naturalToWord64 (Natural -> Word64) -> (Zn n -> Natural) -> Zn n -> Word64
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Zn n -> Natural
    forall (n :: Natural). Zn n -> Natural
    unZn where narrow :: Word64 -> Word32
    narrow (W64# Word64#
    w) = Word32# -> Word32
    W32# (Word# -> Word32#
    wordToWord32# (Word64# -> Word#
    word64ToWord# Word64#
    w))
    instance (KnownNat n, NatWithinBound Word64 n) => From (Zn n) Word64 where
        from :: Zn n -> Word64
    from = Natural -> Word64
    naturalToWord64 (Natural -> Word64) -> (Zn n -> Natural) -> Zn n -> Word64
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Zn n -> Natural
    forall (n :: Natural). Zn n -> Natural
    unZn
    instance (KnownNat n, NatWithinBound Word128 n) => From (Zn n) Word128 where
        from :: Zn n -> Word128
    from = Natural -> Word128
    Word128.fromNatural (Natural -> Word128) -> (Zn n -> Natural) -> Zn n -> Word128
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Zn n -> Natural
    forall (n :: Natural). Zn n -> Natural
    unZn
    instance (KnownNat n, NatWithinBound Word256 n) => From (Zn n) Word256 where
        from :: Zn n -> Word256
    from = Natural -> Word256
    Word256.fromNatural (Natural -> Word256) -> (Zn n -> Natural) -> Zn n -> Word256
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Zn n -> Natural
    forall (n :: Natural). Zn n -> Natural
    unZn

    instance (KnownNat n, NatWithinBound Word64 n) => From (Zn n) (Zn64 n) where
        from :: Zn n -> Zn64 n
    from = Word64 -> Zn64 n
    forall (n :: Natural).
    (KnownNat n, NatWithinBound Word64 n) =>
    Word64 -> Zn64 n
    zn64 (Word64 -> Zn64 n) -> (Zn n -> Word64) -> Zn n -> Zn64 n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Natural -> Word64
    naturalToWord64 (Natural -> Word64) -> (Zn n -> Natural) -> Zn n -> Word64
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Zn n -> Natural
    forall (n :: Natural). Zn n -> Natural
    unZn
    instance KnownNat n => From (Zn64 n) (Zn n) where
        from :: Zn64 n -> Zn n
    from = Natural -> Zn n
    forall (n :: Natural). KnownNat n => Natural -> Zn n
    zn (Natural -> Zn n) -> (Zn64 n -> Natural) -> Zn64 n -> Zn n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Word64 -> Natural
    forall a b. From a b => a -> b
    from (Word64 -> Natural) -> (Zn64 n -> Word64) -> Zn64 n -> Natural
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Zn64 n -> Word64
    forall (n :: Natural). Zn64 n -> Word64
    unZn64

    naturalToWord64 :: Natural -> Word64
    naturalToWord64 :: Natural -> Word64
    naturalToWord64 = Natural -> Word64
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral
    #endif