我有一个字节串b与表单4*N(整数n)的长度,并且希望使用map具有功能f::Word32->Word32上b(以便f被施加到" b[0..3]"," b[4..7]",等等).如何以高效(优雅)的方式完成这项工作?
鉴于和都是操作,您可以非常有效地对它们进行分块:ByteStringB.takeB.dropO(1)
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
chunk :: Int -> ByteString -> [ByteString]
chunk k = takeWhile (not . B.null) . map (B.take k) . iterate (B.drop k)
Run Code Online (Sandbox Code Playgroud)
然后:
\> :set -XOverloadedStrings
\> chunk 4 "abcdefghijkl"
["abcd","efgh","ijkl"]
Run Code Online (Sandbox Code Playgroud)
剩下的就是映射列表,转换为所需类型或从所需类型转换为所需类型,并B.concat在最后进行一次调用。
可以fromByteString使用位移位和左折叠来实现:
import Data.Bits (Bits, shiftL, (.|.))
fromByteString :: (Num a, Bits a) => ByteString -> a
fromByteString = B.foldl go 0
where go acc i = (acc `shiftL` 8) .|. (fromIntegral i)
Run Code Online (Sandbox Code Playgroud)
然后:
\> map fromByteString $ chunk 4 "abcdefghijkl" :: [Word32]
[1633837924,1701209960,1768581996]
Run Code Online (Sandbox Code Playgroud)