Parsing 使用'解析浮点;获取';来自ByteString的测试结果不符合预期

Parsing 使用'解析浮点;获取';来自ByteString的测试结果不符合预期,parsing,haskell,Parsing,Haskell,在创建一个简单的STL解析器的过程中,我在getfromData.Binary中发现了一些意想不到的行为,至少对我来说是这样。在我看来,它并没有停止在我认为应该读取的32位之后读取ByteString {-# LANGUAGE FlexibleContexts #-} module STLTransform where import qualified Data.ByteString.Lazy as BL import Data.Binary import Data.Binary.Get im

在创建一个简单的STL解析器的过程中,我在
get
from
Data.Binary
中发现了一些意想不到的行为,至少对我来说是这样。在我看来,它并没有停止在我认为应该读取的32位之后读取
ByteString

{-# LANGUAGE FlexibleContexts #-}
module STLTransform where

import qualified Data.ByteString.Lazy as BL
import Data.Binary
import Data.Binary.Get
import Data.Binary.Put
import Data.Word
import Numeric.LinearAlgebra
import GHC.Float
import System.Endian

getTriangle = do
  normal   <- getR3
  vertices <- sequence $ take 3 $ trace (show normal) $ repeat getR3
  return (normal, vertices)
  where getR3 = fmap (vector.fmap float2Double)
              $ sequence $ take 3 $ repeat get

getSTL :: Get ([Word8], Word32, [(Vector R, [Vector R])], Word16)
getSTL = do
  header <- sequence $ take 80 $ repeat get
  number <- fmap (toBE32) $ get
  triangles <- sequence $ take (fromIntegral number) $ repeat getTriangle
  attribute <- get
  return (header, number, triangles, attribute)

readSTL fn = BL.readFile fn >>= return.runGet getSTL
在一些调试之后,我将问题隔离到
getTriangle
,更具体地说是
Float
值的解析。通过将
float2Double
替换为
(\a->frompintegral(a::Word32))

与所述问题无关,但已从原始帖子中更正,该属性位于三角形级别,而不是文件级别。

解析一对
(整数,Int)
和,这就是它需要超过32位的原因

这是一个已知的向后兼容性问题:

不要盲目使用
get
,编码的方法不止一种。在这种情况下,对于32位格式的
Float
,还有其他解析器:

*Main STLTransform> readSTL "test.stl"
*** Exception: Data.Binary.Get.runGet at position 1268784: not enough bytes
CallStack (from HasCallStack):
error, called at libraries/binary/src/Data/Binary/Get.hs:351:5 in binary-0.8.6.0:Data.Binary.Get
getTriangle = do
  normal   <- getR3
  vertices <- sequence $ take 3 $ trace (show normal) $ repeat getR3
  return (normal, vertices)
  where getR3 = fmap (vector.fmap (\a -> fromIntegral (a :: Word32)))
              $ sequence $ take 3 $ repeat get
getTriangle :: Get (Vector R, [Vector R], Word16)
getTriangle = do
  normal    <- getR3
  vertices  <- sequence $ take 3 $ repeat getR3
  attribute <- get
  return (normal, vertices, attribute)
  where getR3 = fmap (vector.fmap float2Double)
              $ sequence $ take 3 $ repeat getFloatle