Parsing 使用'解析浮点;获取';来自ByteString的测试结果不符合预期
在创建一个简单的STL解析器的过程中,我在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
get
fromData.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