我正在尝试跟进How to convert a Integer to a ByteString in Haskell。我的目标是创建一个函数toBytes :: Integer -> Int -> ByteString
,它返回一个可能很大Integer
幅度的大端编码。结果ByteString
(懒惰或严格我还不太确定)应该由Int
参数指示。本质上,我想复制python
调用的语义(假设value
是一个非负整数):
value.to_bytes(numBytes, byteorder='big', signed=False)
我不需要拼出所有的东西,我只是在寻找指导。例如,我很高兴能够通过java
toByteArray
上的BigInteger
C#
方法,让我更接近我的最终目标,使用相关的语义(big-endian,两个补码,最小尺寸)或ToByteArray
BigInteger
Data.Binary
(小端,两个补码,最小尺寸)。我可以处理字节序和负数,并添加所需的填充...
我已经指出的帖子推荐了Data.Serialize
和encode
等软件包,但Prelude Data.Binary> encode (0xfffefd :: Integer)
"\NUL\NUL\255\254\253"
Prelude Data.Binary> encode (0xfffefdfc :: Integer)
"\SOH\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\EOT\252\253\254\255"
函数似乎没有遵循明确的编码标准:
Integer
编码类型似乎随着encode
变大而变化,例如从big-endian变为little-endian。所以我想知道,在这些软件包提供的Haskell
函数之上尝试构建自己的函数是否是明智的选择。我担心我的代码将依赖于可能特定于我的主机字节序和/或包版本的实现细节。
我只是这样做,因为我想学习java
。因此,作为一个简单的练习,我尝试使用与BigInteger
toByteArray
相同的API创建一个类型(尽管有更好的{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import qualified Data.ByteString.Lazy as L
import Data.Hashable
type ByteArray = L.ByteString
newtype Sign = Sign Int
newtype NumBytes = NumBytes Int
newtype Number = Number Integer
deriving (Eq, Ord, Num, Real, Enum, Integral, Hashable)
fromBytes :: Sign -> ByteArray -> Number
toBytes :: Number -> NumBytes -> ByteArray
):
{{1}}
任何指导都热烈赞赏