{-# 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
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 :: 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 :: 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 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# Int#
i) = Int# -> Int16
I16# (Int# -> Int#
int8ToInt16# Int#
i)
instance From Int8 Int32 where
    from :: Int8 -> Int32
from (I8# Int#
i) = Int# -> Int32
I32# (Int# -> Int#
int8ToInt32# Int#
i)
instance From Int8 Int64 where
    from :: Int8 -> Int64
from (I8# Int#
i) = Int -> Int64
intToInt64 (Int# -> Int
I# (Int# -> Int#
int8ToInt# Int#
i))
instance From Int8 Int where
    from :: Int8 -> Int
from (I8# Int#
i) = Int# -> Int
I# (Int# -> Int#
int8ToInt# Int#
i)

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

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

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

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

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

instance From Word32 Word64 where
    from :: Word32 -> Word64
from (W32# Word#
i) = Word -> Word64
wordToWord64 (Word# -> Word
W# (Word# -> Word#
word32ToWord# Word#
i))
instance From Word32 Word128 where
    from :: Word32 -> Word128
from (W32# Word#
i) = Word64 -> Word64 -> Word128
Word128 Word64
0 (Word -> Word64
wordToWord64 (Word -> Word64) -> Word -> Word64
forall a b. (a -> b) -> a -> b
$ Word# -> Word
W# (Word# -> Word#
word32ToWord# Word#
i))
instance From Word32 Word256 where
    from :: Word32 -> Word256
from (W32# Word#
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# (Word# -> Word#
word32ToWord# Word#
i))
instance From Word32 Word where
    from :: Word32 -> Word
from (W32# Word#
i) = Word# -> Word
W# (Word# -> Word#
word32ToWord# Word#
i)
instance From Word32 Int64 where
    from :: Word32 -> Int64
from (W32# Word#
w) = Int -> Int64
intToInt64 (Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
word32ToWord# Word#
w)))
instance From Word32 Int where
    from :: Word32 -> Int
from (W32# Word#
w) = Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
word32ToWord# Word#
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 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 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 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 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 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 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 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 :: Nat) 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 :: Nat) (m :: Nat) 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 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 :: Nat) 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 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 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 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 :: Nat) 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 :: Nat) 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 :: Nat) 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 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 :: Nat) 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 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 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 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 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 :: Nat). Zn64 n -> Word64
unZn64 where narrow :: Word64 -> Word8
narrow (W64# Word#
w) = Word# -> Word8
W8# (Word# -> Word#
wordToWord8# (Word# -> Word#
word64ToWord# Word#
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 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 :: Nat). Zn64 n -> Word64
unZn64 where narrow :: Word64 -> Word16
narrow (W64# Word#
w) = Word# -> Word16
W16# (Word# -> Word#
wordToWord16# (Word# -> Word#
word64ToWord# Word#
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 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 :: Nat). Zn64 n -> Word64
unZn64 where narrow :: Word64 -> Word32
narrow (W64# Word#
w) = Word# -> Word32
W32# (Word# -> Word#
wordToWord32# (Word# -> Word#
word64ToWord# Word#
w))
instance From (Zn64 n) Word64 where
    from :: Zn64 n -> Word64
from = Zn64 n -> Word64
forall (n :: Nat). 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 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 :: Nat). 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 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 :: Nat). 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 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 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 :: Nat). Zn n -> Natural
unZn where narrow :: Word64 -> Word8
narrow (W64# Word#
w) = Word# -> Word8
W8# (Word# -> Word#
wordToWord8# (Word# -> Word#
word64ToWord# Word#
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 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 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 :: Nat). Zn n -> Natural
unZn where narrow :: Word64 -> Word16
narrow (W64# Word#
w) = Word# -> Word16
W16# (Word# -> Word#
wordToWord16# (Word# -> Word#
word64ToWord# Word#
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 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 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 :: Nat). Zn n -> Natural
unZn where narrow :: Word64 -> Word32
narrow (W64# Word#
w) = Word# -> Word32
W32# (Word# -> Word#
wordToWord32# (Word# -> Word#
word64ToWord# Word#
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 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 :: Nat). 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 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 :: Nat). 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 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 :: Nat). 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 :: Nat).
(KnownNat n, NatWithinBound Word64 n) =>
Word64 -> Zn64 n
zn64 (Word64 -> Zn64 n) -> (Zn n -> Word64) -> Zn n -> Zn64 n
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 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 :: Nat). Zn n -> Natural
unZn
instance KnownNat n => From (Zn64 n) (Zn n) where
    from :: Zn64 n -> Zn n
from = Natural -> Zn n
forall (n :: Nat). KnownNat n => Natural -> Zn n
zn (Natural -> Zn n) -> (Zn64 n -> Natural) -> Zn64 n -> Zn n
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 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 :: Nat). 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