首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell中ByteString和ByteString.Lazy的通用函数

Haskell中ByteString和ByteString.Lazy的通用函数
EN

Stack Overflow用户
提问于 2014-02-06 08:26:11
回答 3查看 290关注 0票数 7

我实现了读取ByteString并以十六进制格式转换它的函数。例如,给定"AA10“,它将其转换为170,16

代码语言:javascript
复制
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Internal as BS (w2c)

rHex :: BSL.ByteString -> BSL.ByteString
rHex bs
    | BSL.null bs = BSL.empty
    | BSL.null rest' = fromHex c1 `BSL.cons` BSL.empty
    | otherwise = rChunk c1 c2 `BSL.cons` rHex rest
          where (c1, rest') = (BSL.head bs, BSL.tail bs)
                (c2, rest) = (BSL.head rest', BSL.tail rest')
                rChunk c1 c2 = (fromHex c1) * 16 + fromHex c2
fromHex = fromIntegral . digitToInt . BS.w2c

但是,我意识到,除了简单的ByteString之外,我还需要相同的函数,而不是延迟。我想出的唯一办法是这样的:

代码语言:javascript
复制
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString as BS
import qualified Data.ByteString.Internal as BS (w2c)

rHex' funcs@(null, empty, cons, head, tail, fromHex) bs
    | null bs = empty
    | null rest' = fromHex c1 `cons` empty
    | otherwise = rChunk c1 c2 `cons` rHex' funcs rest
          where (c1, rest') = (head bs, tail bs)
                (c2, rest) = (head rest', tail rest')
                rChunk c1 c2 = (fromHex c1) * 16 + fromHex c2

fromHex = fromIntegral . digitToInt . BS.w2c

rHexBSL :: BSL.ByteString -> BSL.ByteString
rHexBSL = rHex' (BSL.null, BSL.empty, BSL.cons, BSL.head, BSL.tail, fromHex)

rHexBS :: BS.ByteString -> BS.ByteString
rHexBS = rHex' (BS.null, BS.empty, BS.cons, BS.head, BS.tail, fromHex)

因此,我在函数rHex'中直接将所有需要的函数传递给rHexBSL rHexBS。还有更多的Haskell方法来为Bytestring和Bytestring.Lazy创建一个通用函数吗?或者创建类型类什么的?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-02-06 08:57:51

我会简化这一点,方法是使用[Word8],并对每种类型的ByteString使用packunpack来获得您想要的东西--例如:

代码语言:javascript
复制
toHex :: Word8 -> Word8 -> Word8
toHex a b = (fromHex a) * 16 + fromHex b

hexify :: [Word8] -> [Word8] -> [Word8]
hexify (a:b:cs) = toHex a b : hexify cs
hexify [b]      = toHex 0 b
hexify []       = []

rHexBSL :: BSL.ByteString -> BSL.ByteString
rHexBSL = BSL.pack . hexify . BSL.unpack

rHexBS :: BS.ByteString -> BS.ByteString
rHexBS = BS.pack . hexify . BS.unpack

我认为这样做很有可能实现融合,从而提高操作的效率。

尽管如此,看看布莱恩是如何在他的base16 16-字节串包中做到这一点,这是很有教育意义的。

  • Data.ByteString编码
  • Data.ByteString.Lazy编码
票数 3
EN

Stack Overflow用户

发布于 2014-02-06 08:40:36

您可以始终使用来自toStrictfromStrictData.ByteString.Lazy函数在严格类型和惰性类型之间来回转换。在这种情况下:

代码语言:javascript
复制
rHexBS = BSL.toStrict . hHexBSL . BSL.fromStrict
票数 3
EN

Stack Overflow用户

发布于 2014-02-07 05:42:54

有一个类要交镜头包http://hackage.haskell.org/package/lens-4.0.1/docs/Data-ByteString-Lens.html#v:packedBytes。因此,给定user5402 5402的十六化代码,我猜应该是

代码语言:javascript
复制
 hexify :: [Word8] -> [Word8]
 hexify (a:b:cs) = toHex a b : hexify cs
 hexify [b]      = [toHex 0 b]
 hexify []       = []

您将发现(在范围内也有Control.Lens.under )您可以编写

代码语言:javascript
复制
 rHex :: IsByteString b => b -> b 
 rHex = under packedBytes hexify

做其他类似的事情。它可能比它更麻烦,它是值得的;我提到它,因为有一个合适的课程在那里。under packedBytes f只是对令人厌烦的pack . f . unpack业务进行了编码,但涵盖了pack的两种含义。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21597543

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档