packages feed

borsh 0.1.0 → 0.2.0

raw patch · 14 files changed

+105/−240 lines, 14 filesdep −memorydep ~wide-wordPVP ok

version bump matches the API change (PVP)

Dependencies removed: memory

Dependency ranges changed: wide-word

API changes (from Hackage documentation)

- Codec.Borsh.Incremental: Decoder :: (LocatedChunk -> ST s (LocatedChunk, DecodeResult s a)) -> Decoder s a
- Codec.Borsh.Incremental: L :: !a -> {-# UNPACK #-} !ByteOffset -> Located a
- Codec.Borsh.Incremental: [DecodeDone] :: a -> DecodeResult s a
- Codec.Borsh.Incremental: [DecodeFail] :: String -> DecodeResult s a
- Codec.Borsh.Incremental: [DecodeIncremental] :: Word32 -> Decoder s a -> ([a] -> Decoder s b) -> DecodeResult s b
- Codec.Borsh.Incremental: [DecodeIncremental_] :: Word32 -> Decoder s () -> Decoder s a -> DecodeResult s a
- Codec.Borsh.Incremental: [DecodeLargeToken] :: Word32 -> (ByteString -> Decoder s a) -> DecodeResult s a
- Codec.Borsh.Incremental: [DecodeNeedsData] :: Decoder s a -> DecodeResult s a
- Codec.Borsh.Incremental: [matchChunk] :: Decoder s a -> LocatedChunk -> ST s (LocatedChunk, DecodeResult s a)
- Codec.Borsh.Incremental: data DecodeResult s a
- Codec.Borsh.Incremental: data Located a
- Codec.Borsh.Incremental: decodeLittleEndian :: forall s a. ByteSwap a => Decoder s a
- Codec.Borsh.Incremental: newtype Decoder s a
- Codec.Borsh.Incremental: type ByteOffset = Word32
- Codec.Borsh.Incremental: type LocatedChunk = Located ByteString
- Data.Int128: data Int128
- Data.Int128: instance Codec.Borsh.Internal.Util.ByteSwap.ByteSwap Data.Int128.Int128
- Data.Int128: instance Data.Data.Data Data.Int128.Int128
- Data.Int128: instance Foreign.Storable.Storable Data.Int128.Int128
- Data.Int128: instance GHC.Bits.Bits Data.Int128.Int128
- Data.Int128: instance GHC.Bits.FiniteBits Data.Int128.Int128
- Data.Int128: instance GHC.Classes.Eq Data.Int128.Int128
- Data.Int128: instance GHC.Classes.Ord Data.Int128.Int128
- Data.Int128: instance GHC.Enum.Bounded Data.Int128.Int128
- Data.Int128: instance GHC.Enum.Enum Data.Int128.Int128
- Data.Int128: instance GHC.Generics.Generic Data.Int128.Int128
- Data.Int128: instance GHC.Ix.Ix Data.Int128.Int128
- Data.Int128: instance GHC.Num.Num Data.Int128.Int128
- Data.Int128: instance GHC.Read.Read Data.Int128.Int128
- Data.Int128: instance GHC.Real.Integral Data.Int128.Int128
- Data.Int128: instance GHC.Real.Real Data.Int128.Int128
- Data.Int128: instance GHC.Show.Show Data.Int128.Int128
- Data.Int128: int128 :: Word64 -> Word64 -> Int128
- Data.Int128: int128LS64 :: Int128 -> Word64
- Data.Int128: int128MS64 :: Int128 -> Word64
- Data.Word128: data Word128
- Data.Word128: instance Codec.Borsh.Internal.Util.ByteSwap.ByteSwap Data.Word128.Word128
- Data.Word128: instance Data.Data.Data Data.Word128.Word128
- Data.Word128: instance Foreign.Storable.Storable Data.Word128.Word128
- Data.Word128: instance GHC.Bits.Bits Data.Word128.Word128
- Data.Word128: instance GHC.Bits.FiniteBits Data.Word128.Word128
- Data.Word128: instance GHC.Classes.Eq Data.Word128.Word128
- Data.Word128: instance GHC.Classes.Ord Data.Word128.Word128
- Data.Word128: instance GHC.Enum.Bounded Data.Word128.Word128
- Data.Word128: instance GHC.Enum.Enum Data.Word128.Word128
- Data.Word128: instance GHC.Generics.Generic Data.Word128.Word128
- Data.Word128: instance GHC.Ix.Ix Data.Word128.Word128
- Data.Word128: instance GHC.Num.Num Data.Word128.Word128
- Data.Word128: instance GHC.Read.Read Data.Word128.Word128
- Data.Word128: instance GHC.Real.Integral Data.Word128.Word128
- Data.Word128: instance GHC.Real.Real Data.Word128.Word128
- Data.Word128: instance GHC.Show.Show Data.Word128.Word128
- Data.Word128: word128 :: Word64 -> Word64 -> Word128
- Data.Word128: word128LS64 :: Word128 -> Word64
- Data.Word128: word128MS64 :: Word128 -> Word64
+ Codec.Borsh.Incremental: data Decoder s a

Files

CHANGELOG.md view
@@ -1,5 +1,12 @@ # Revision history for borsh +## 0.2.0 -- 2022-11-15++* Remove dependency on `memory`+* Don't newtype-wrap `Int128` and `Word128`+* Improve documentation of the incremental interface+* Make size argument to `FixedSizeArray` nominal+ ## 0.1.0 -- 2022-11-11  * First released version
borsh.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               borsh-version:            0.1.0+version:            0.2.0 synopsis:           Implementation of BORSH serialisation description:   This package provides type classes and combinators for@@ -23,6 +23,13 @@ extra-doc-files:    CHANGELOG.md bug-reports:        https://github.com/well-typed/borsh/issues +tested-with:+    GHC == 8.6.5+  , GHC == 8.8.3+  , GHC == 8.10.7+  , GHC == 9.0.2+  , GHC == 9.2.2+ source-repository head   type:     git   location: https://github.com/well-typed/borsh@@ -75,8 +82,6 @@       Codec.Borsh.Incremental        Data.FixedSizeArray-      Data.Int128-      Data.Word128   other-modules:       Codec.Borsh.Class       Codec.Borsh.Decoding@@ -94,7 +99,6 @@     , bytestring       >= 0.10 && < 0.12     , containers       >= 0.6  && < 0.7     , generics-sop     >= 0.5  && < 0.6-    , memory           >= 0.17 && < 0.19.0     , sop-core         >= 0.5  && < 0.6     , text             >= 1.2  && < 2.1 @@ -136,3 +140,4 @@     , tasty     , tasty-quickcheck     , text+    , wide-word
src/Codec/Borsh/Class.hs view
@@ -23,6 +23,8 @@ import Data.Proxy import Data.Set (Set) import Data.Text (Text)+import Data.WideWord.Int128+import Data.WideWord.Word128 import Data.Word import Generics.SOP import GHC.TypeNats@@ -35,8 +37,6 @@ import Codec.Borsh.Encoding import Codec.Borsh.Incremental import Data.FixedSizeArray (FixedSizeArray)-import Data.Int128-import Data.Word128 (Word128)  {-------------------------------------------------------------------------------   Size information
src/Codec/Borsh/Decoding.hs view
@@ -36,6 +36,8 @@ import Data.Set (Set) import Data.STRef import Data.Text (Text)+import Data.WideWord.Word128+import Data.WideWord.Int128 import Data.Word import Generics.SOP import GHC.TypeLits@@ -49,11 +51,10 @@ import qualified Data.Vector.Generic.Mutable as GM  import Codec.Borsh.Incremental+import Codec.Borsh.Incremental.Decoder (decodeLittleEndian) import Codec.Borsh.Internal.Util.BitwiseCast import Codec.Borsh.Internal.Util.SOP import Data.FixedSizeArray (FixedSizeArray, MFixedSizeArray)-import Data.Word128 (Word128)-import Data.Int128 (Int128)  import qualified Data.FixedSizeArray as FSA 
src/Codec/Borsh/Encoding.hs view
@@ -39,6 +39,8 @@ import Data.Set (Set) import Data.SOP import Data.Text (Text)+import Data.WideWord.Word128+import Data.WideWord.Int128 import Data.Word  import qualified Data.ByteString         as S@@ -51,8 +53,6 @@ import Data.FixedSizeArray (FixedSizeArray) import Codec.Borsh.Internal.Util.ByteString import Codec.Borsh.Internal.Util.SOP (indices)-import Data.Word128-import Data.Int128  {-------------------------------------------------------------------------------   Encoder definition@@ -99,11 +99,11 @@  encodeU128 :: Encoder Word128 encodeU128 = Encoder $-    \w128 -> B.word64LE (word128LS64 w128) <> B.word64LE (word128MS64 w128)+    \w128 -> B.word64LE (word128Lo64 w128) <> B.word64LE (word128Hi64 w128)  encodeI128 :: Encoder Int128 encodeI128 = Encoder $-    \i128 -> B.word64LE (int128LS64 i128) <> B.word64LE (int128MS64 i128)+    \i128 -> B.word64LE (int128Lo64 i128) <> B.word64LE (int128Hi64 i128)  -- Encoding 'Text' --
src/Codec/Borsh/Incremental.hs view
@@ -1,27 +1,18 @@-+-- | Interface for incremental decoding module Codec.Borsh.Incremental (-    -- * Constructing decoders-    Decoder(..)-  , DecodeResult(..)+    -- * Definition+    Decoder -- Opaque   , liftDecoder+     -- * Running decoders   , DeserialiseFailure(..)   , deserialiseByteString-    -- * Specialised decoders-    ---    -- | These functions comprise a low-level decoder interface which will not-    -- be necessary for most applications. Most applications should simply use-    -- 'Codec.Borsh.Class.deserialiseBorsh'-  , decodeLittleEndian++    -- * Large tokens   , decodeLargeToken   , decodeIncremental   , decodeIncremental_-    -- * Located values-  , Located(..)-  , ByteOffset-  , LocatedChunk   ) where  import Codec.Borsh.Incremental.Decoder-import Codec.Borsh.Incremental.Located import Codec.Borsh.Incremental.Monad
src/Codec/Borsh/Incremental/Decoder.hs view
@@ -35,6 +35,8 @@ -- | Decoder -- -- A decoder describes how to match against a single chunk of the input.+--+-- For decoders for primitive types, use 'Codec.Borsh.FromBorsh' instances. newtype Decoder s a = Decoder {       matchChunk :: LocatedChunk -> ST s (LocatedChunk, DecodeResult s a)     }@@ -43,9 +45,12 @@   Operations supported by the 'Decoder' monad -------------------------------------------------------------------------------} +-- | Lift an 'ST' operation into the 'Decoder' monad. liftDecoder :: ST s a -> Decoder s a liftDecoder sa = Decoder $ \chunk -> (chunk, ) . DecodeDone <$> sa +-- | Decode a value encoded in little endian byte order (e.g. as mandated by the+-- [Borsh](https://borsh.io) spec). decodeLittleEndian :: forall s a. ByteSwap a => Decoder s a decodeLittleEndian = Decoder aux   where@@ -57,15 +62,43 @@           Nothing ->             return (chunk, DecodeNeedsData decodeLittleEndian) -decodeLargeToken :: Word32 -> Decoder s L.ByteString+-- | Large token of known length that spans multiple chunks+--+-- This is NOT incremental: all chunks will be read into memory before the+-- result is returned. Primarily useful for large types that are not+-- easily split into (valid) chunks, such as UTF8-encoded text (if were+-- wanted to split that, we'd have to split it at UTF8 boundaries).+decodeLargeToken ::+     Word32 -- ^ Number of bytes to decode+  -> Decoder s L.ByteString decodeLargeToken n = Decoder $ \chunk ->     return (chunk, DecodeLargeToken n return) -decodeIncremental :: Word32 -> Decoder s a -> Decoder s [a]+-- | Incremental interface+--+-- When decoding large objects such as lists, we do not want to bring all+-- required chunks into memory before decoding the list. Instead, we want to+-- decode the list elements as we go. In this case, 'DecodeIncremental' can+-- be used to repeatedly decode a value using decoder for the elements.+--+-- NOTE: This interface is incremental in the sense that the /input chunks/+-- are read one at a time. It is /NOT/ incremental in the generated /output/.+decodeIncremental ::+     Word32      -- ^ Number of elements in the sequence to decode+  -> Decoder s a -- ^ 'Decoder' to run for the individual elements+  -> Decoder s [a] decodeIncremental n d = Decoder $ \chunk ->     return (chunk, DecodeIncremental n d return) -decodeIncremental_ :: Word32 -> Decoder s () -> Decoder s ()+-- | Variation on 'decoreIncremental', where we do not accumulate results+--+-- This is useful for example for datatypes that we can update imperatively+-- (using the 'ST' monad), such as mutable arrays. It could also be used to skip+-- over unused parts of the input.+decodeIncremental_ ::+     Word32       -- ^ Number of elements in the sequence to decode+  -> Decoder s () -- ^ 'Decoder' to run for the individual elements+  -> Decoder s () decodeIncremental_ n d = Decoder $ \chunk ->     return (chunk, DecodeIncremental_ n d $ return ()) @@ -90,10 +123,7 @@    -- | Large token of known length that spans multiple chunks   ---  -- This is NOT incremental: all chunks will be read into memory before the-  -- function is applied. Primarily useful for large types that are not-  -- easily split into (valid) chunks, such as UTF8-encoded text (if were-  -- wanted to split that, we'd have to split it at UTF8 boundaries).+  -- See 'decodeLargeToken' for discussion.   --   -- The continuation will be called with a lazy bytestring of precisely the   -- requested length (provided enough input is available, of course), along@@ -105,14 +135,7 @@    -- | Incremental interface   ---  -- When decoding large objects such as lists, we do not want to bring all-  -- required chunks into memory before decoding the list. Instead, we want to-  -- decode the list elements as we go. In this case, 'DecodeIncremental' can-  -- be used to repeatedly decode a value using decoder for the elements; when-  -- all elements have been processed, the continuation decoder is called.-  ---  -- NOTE: This interface is incremental in the sense that the /input chunks/-  -- are read one at a time. It is /NOT/ incremental in the generated /output/.+  -- See 'decodeIncremental' for discussion.   DecodeIncremental ::        Word32               -- ^ How often to repeat the smaller decoder     -> Decoder s a          -- ^ Decoder to repeat@@ -121,9 +144,7 @@    -- | Variation on 'DecodeIncremental', where we do not accumulate results   ---  -- This is useful for example for datatypes that we can update imperatively,-  -- such as mutable arrays. It could also be used to skip over unused parts-  -- of the input.+  -- See 'decodeIncremental_' for discussion.   DecodeIncremental_ ::        Word32        -- ^ How often to repeat the smaller decoder     -> Decoder s ()  -- ^ Decoder to repeat (imperatively handling each element)@@ -256,8 +277,13 @@   Top-level API -------------------------------------------------------------------------------} +-- | Run decoder deserialiseByteString ::      (forall s. Decoder s a)+  -- ^ Decoder   -> L.ByteString+  -- ^ Input   -> Either DeserialiseFailure (L.ByteString, ByteOffset, a)+  -- ^ Left-over input, offset of the left-over input relative to the start,+  -- and the result. deserialiseByteString d = runIDecode (runIncr (runDecoder d))
src/Codec/Borsh/Internal/Util/BitwiseCast.hs view
@@ -1,11 +1,11 @@ module Codec.Borsh.Internal.Util.BitwiseCast (BitwiseCast(..)) where  import Data.Int+import Data.WideWord.Int128+import Data.WideWord.Word128 import Data.Word import GHC.Float -import Data.Int128 (Int128)-import Data.Word128 (Word128)  class BitwiseCast a b where   -- | Bit-for-bit copy from @a@ to @b@
src/Codec/Borsh/Internal/Util/ByteSwap.hs view
@@ -5,47 +5,30 @@ -- be necessary anymore. module Codec.Borsh.Internal.Util.ByteSwap (     ByteSwap(..)-  , LE(..)-  , toLE+  , LE (..)   , fromLE-  , BE(..)-  , toBE-  , fromBE   ) where +import Data.WideWord.Int128+import Data.WideWord.Word128 import Data.Word import Foreign (Storable)--import Data.Memory.Endian (getSystemEndianness, Endianness(LittleEndian))+import GHC.ByteOrder (targetByteOrder, ByteOrder (..))  -- | Little Endian value newtype LE a = LE { unLE :: a }   deriving newtype (Show, Eq, Storable) --- | Big Endian value-newtype BE a = BE { unBE :: a }-  deriving newtype (Show, Eq, Storable)---- | Convert a value in cpu endianess to big endian-toBE :: ByteSwap a => a -> BE a-toBE = BE . (if getSystemEndianness == LittleEndian then byteSwap else id)---- | Convert from a big endian value to the cpu endianness-fromBE :: ByteSwap a => BE a -> a-fromBE (BE a) = if getSystemEndianness == LittleEndian then byteSwap a else a---- | Convert a value in cpu endianess to little endian-toLE :: ByteSwap a => a -> LE a-toLE = LE . (if getSystemEndianness == LittleEndian then id else byteSwap)- -- | Convert from a little endian value to the cpu endianness fromLE :: ByteSwap a => LE a -> a-fromLE (LE a) = if getSystemEndianness == LittleEndian then a else byteSwap a+fromLE (LE a) = if targetByteOrder == LittleEndian then a else byteSwap a  class Storable a => ByteSwap a where   byteSwap :: a -> a -instance ByteSwap Word8  where byteSwap = id-instance ByteSwap Word16 where byteSwap = byteSwap16-instance ByteSwap Word32 where byteSwap = byteSwap32-instance ByteSwap Word64 where byteSwap = byteSwap64+instance ByteSwap Word8   where byteSwap = id+instance ByteSwap Word16  where byteSwap = byteSwap16+instance ByteSwap Word32  where byteSwap = byteSwap32+instance ByteSwap Word64  where byteSwap = byteSwap64+instance ByteSwap Word128 where byteSwap = byteSwapWord128+instance ByteSwap Int128  where byteSwap = byteSwapInt128
src/Data/FixedSizeArray.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE RoleAnnotations #-} -- | Fixed size arrays -- -- Intended for qualified import@@ -35,6 +36,7 @@ -- -- NOTE: For convenience, this is an instance of 'G.Vector', but the invariant -- that the length of the vector should never change is not currently checked.+type role FixedSizeArray nominal _ newtype FixedSizeArray (n :: Nat) (a :: Type) = FromArray {       toArray :: Vector a     }
− src/Data/Int128.hs
@@ -1,74 +0,0 @@-{-# LANGUAGE DeriveDataTypeable #-}--module Data.Int128 (-    -- * Definition-    Int128 -- Opaque-    -- * Construction-  , int128-    -- * Destruction-  , int128MS64-  , int128LS64-  ) where--import Data.Bits-import Data.Data-import Data.Ix-import Data.Word-import Foreign-import GHC.Generics--import qualified Data.WideWord.Int128 as WW--import Codec.Borsh.Internal.Util.ByteSwap (ByteSwap(..))--{--------------------------------------------------------------------------------  Definition, construction, destruction--------------------------------------------------------------------------------}---- | Signed 128-bit word------ Implementation note: this currently relies on the implementation of the--- [wide-word](https://hackage.haskell.org/package/wide-word) package, with some--- additional instances. However, the use of @wide-word@ is not part of the--- public API of the @borsh@ package.-newtype Int128 = Int128 WW.Int128-  deriving stock Data-  deriving newtype (-      Bits-    , Bounded-    , Enum-    , Eq-    , FiniteBits-    , Generic-    , Integral-    , Ix-    , Num-    , Ord-    , Read-    , Real-    , Show-    , Storable-    )---- | Construct an 'Int128'-int128 ::-     Word64 -- ^ Most significant bits-  -> Word64 -- ^ Least significant bits-  -> Int128-int128 hi lo = Int128 (WW.Int128 hi lo)---- | Get the most significant 64 bits from an 'Int128'-int128MS64 :: Int128 -> Word64-int128MS64 (Int128 (WW.Int128 hi _)) = hi---- | Get the least significant 64 bits from an 'Int128'-int128LS64 :: Int128 -> Word64-int128LS64 (Int128 (WW.Int128 _ lo)) = lo--{--------------------------------------------------------------------------------  Instances--------------------------------------------------------------------------------}--instance ByteSwap Int128 where-  byteSwap (Int128 (WW.Int128 hi lo)) =-      Int128 $ WW.Int128 (byteSwap64 lo) (byteSwap64 hi)
− src/Data/Word128.hs
@@ -1,74 +0,0 @@-{-# LANGUAGE DeriveDataTypeable #-}--module Data.Word128 (-    -- * Definition-    Word128 -- opaque-    -- * Construction-  , word128-    -- * Destruction-  , word128MS64-  , word128LS64-  ) where--import Data.Bits-import Data.Data-import Data.Ix-import Data.Word-import Foreign-import GHC.Generics--import qualified Data.WideWord.Word128 as WW--import Codec.Borsh.Internal.Util.ByteSwap (ByteSwap(..))--{--------------------------------------------------------------------------------  Definition, construction, destruction--------------------------------------------------------------------------------}---- | Unsigned 128-bit word------ Implementation note: this currently relies on the implementation of the--- [wide-word](https://hackage.haskell.org/package/wide-word) package, with some--- additional instances. However, the use of @wide-word@ is not part of the--- public API of the @borsh@ package.-newtype Word128 = Word128 WW.Word128-  deriving stock Data-  deriving newtype (-      Bits-    , Bounded-    , Enum-    , Eq-    , FiniteBits-    , Generic-    , Integral-    , Ix-    , Num-    , Ord-    , Read-    , Real-    , Show-    , Storable-    )---- | Construct a 'Word128'-word128 ::-     Word64 -- ^ Most significant bits-  -> Word64 -- ^ Least significant bits-  -> Word128-word128 hi lo = Word128 (WW.Word128 hi lo)---- | Get the most significant 64 bits from a 'Word128'-word128MS64 :: Word128 -> Word64-word128MS64 (Word128 (WW.Word128 hi _)) = hi---- | Get the least significant 64 bits from a 'Word128'-word128LS64 :: Word128 -> Word64-word128LS64 (Word128 (WW.Word128 _ lo)) = lo--{--------------------------------------------------------------------------------  Instances--------------------------------------------------------------------------------}--instance ByteSwap Word128 where-  byteSwap (Word128 (WW.Word128 hi lo)) =-      Word128 $ WW.Word128 (byteSwap64 lo) (byteSwap64 hi)
test/Test/Codec/Borsh/Util/Orphans.hs view
@@ -6,35 +6,34 @@ import Data.SOP import qualified Data.Text as Text import Data.Text (Text)+import Data.WideWord.Word128+import Data.WideWord.Int128 import GHC.TypeLits import Test.QuickCheck hiding (Fn) - import Data.FixedSizeArray (FixedSizeArray)-import Data.Word128-import Data.Int128  import qualified Data.FixedSizeArray as FSA  instance Arbitrary Word128 where-  arbitrary = word128 <$> arbitrary <*> arbitrary+  arbitrary = Word128 <$> arbitrary <*> arbitrary   shrink w128 = concat [-        [word128 hi' lo  | hi' <- shrink hi]-      , [word128 hi  lo' | lo' <- shrink lo]+        [Word128 hi' lo  | hi' <- shrink hi]+      , [Word128 hi  lo' | lo' <- shrink lo]       ]     where-      hi = word128MS64 w128-      lo = word128LS64 w128+      hi = word128Hi64 w128+      lo = word128Lo64 w128  instance Arbitrary Int128 where-  arbitrary = int128 <$> arbitrary <*> arbitrary+  arbitrary = Int128 <$> arbitrary <*> arbitrary   shrink i128 = concat [-        [int128 hi' lo  | hi' <- shrink hi]-      , [int128 hi  lo' | lo' <- shrink lo]+        [Int128 hi' lo  | hi' <- shrink hi]+      , [Int128 hi  lo' | lo' <- shrink lo]       ]     where-      hi = int128MS64 i128-      lo = int128LS64 i128+      lo = int128Lo64 i128+      hi = int128Hi64 i128  instance Arbitrary Text where   arbitrary = Text.pack <$> arbitrary@@ -43,4 +42,3 @@ instance (KnownNat n, Arbitrary a) => Arbitrary (FixedSizeArray n a) where   arbitrary = FSA.fromList <$>       replicateM (fromIntegral $ natVal (Proxy @n)) arbitrary-
test/Test/Codec/Borsh/Util/RandomType.hs view
@@ -18,15 +18,15 @@ import Data.FixedSizeArray (FixedSizeArray) import Data.Foldable (toList) import Data.Int-import Data.Int128 import Data.Kind import Data.Map (Map) import Data.Maybe (mapMaybe, maybeToList) import Data.Profunctor import Data.Set (Set) import Data.Text (Text)+import Data.WideWord.Int128+import Data.WideWord.Word128 import Data.Word-import Data.Word128 import Generics.SOP import Generics.SOP.Dict import Generics.SOP.NP (map_NP)@@ -371,7 +371,7 @@ shrinkIntegral = ShrinkFun $ return . fromIntegral  shrinkU128 :: ShrinkFun Word128 Word64-shrinkU128 = ShrinkFun $ return . word128LS64+shrinkU128 = ShrinkFun $ return . word128Lo64  shrinkDouble :: ShrinkFun Double Word64 shrinkDouble = ShrinkFun $ return . castDoubleToWord64