Haskell 断开的用户,断开的数据。二进制还是断开的安装?
我试图使用Data.Binary来序列化映射,但出现了一个错误:字节不足。然后我尝试用一个更简单的例子来处理一个整数列表,在这里,它也不起作用。可能出了什么问题?我的代码中是否有错误,我误解了什么,或者我的安装可能有问题,在这种情况下,我如何解决它 下面是我的测试代码Haskell 断开的用户,断开的数据。二进制还是断开的安装?,haskell,serialization,Haskell,Serialization,我试图使用Data.Binary来序列化映射,但出现了一个错误:字节不足。然后我尝试用一个更简单的例子来处理一个整数列表,在这里,它也不起作用。可能出了什么问题?我的代码中是否有错误,我误解了什么,或者我的安装可能有问题,在这种情况下,我如何解决它 下面是我的测试代码 import Data.Binary worldfile = "binarysimple.world" main = do ser <- decodeFileOrFail worldfile case ser of
import Data.Binary
worldfile = "binarysimple.world"
main = do
ser <- decodeFileOrFail worldfile
case ser of
Right w -> showWorld $ show (w :: [Int])
Left (_,s) -> putStrLn ("the error:"++s) >> newworld
newworld = do
let world = [1,2,3] :: [Int]
showWorld $ show world
encodeFile worldfile $ encode world
showWorld = putStrLn
我不知道确切的格式,但这可能是合理的输出:
$ hexdump -C binarysimple.world
00000000 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 03 |....... ........|
00000010 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 02 |................|
00000020 00 00 00 00 00 00 00 03 |........|
00000028
问题
让我们回顾一下你认为你在做什么以及你在做什么
您认为您正在使用binary
对Int
s列表进行编码,并通过testring将其写入文件。然后,从文件中读取并解码Int
s列表,结果失败
实际上,您要做的是将Int
s列表编码为bytestring,然后将该bytestring编码为bytestring(因此,在字节前添加了一个额外的长度字段),并将该bytestring写入磁盘。然后解码失败,因为磁盘上有encode(列表))
而不是encode(列表)
解决方案
只需将行改为:
encodeFile worldfile $ encode world
到
读取十六进制转储
因此,可以将上面的hextump读取为一系列64位整数:0x20、3、1、2、3。第一个值,十进制32,是Bytestring
编码的一部分,指示剩余Bytestring的长度(8字节*4整数)。第二个值3是列表编码的一部分,它表示列表的长度。最终值是列表中的各个元素
最后,您不需要一些随机的在线人员向您解释格式,您可以从binary
包中的实例中读取格式(一旦您对Haskell足够熟悉)
encodeFile worldfile $ encode world
encodeFile worldfile world
00000000 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 03 |....... ........|
00000010 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 02 |................|
00000020 00 00 00 00 00 00 00 03