haskell - 获取 Data.ByteString.Builder 的长度

标签 haskell

我有一个函数tabulate,它接受一个对象列表,以及一个将这些对象的字段转换为Builders的函数列表。它返回一个表示格式良好的表格的 Builder。例如:

tabulate :: [a -> Builder] -> [a] -> Builder
tabulate = ...
data Assc = Assc { key :: String, value :: String }

> let funcs = [string7 . key, const $ char7 '=', string7 . value ]
> let objs = ["short" `Assc` "a", "longer" `Assc` "b", "waylongername" `Assc` "c"]
> hPutBuilder stdout $ tabulate funcs objs
short         = a
longer        = b
waylongername = c

为此,我需要确定每列的最大长度。目前我在每个元素上使用 toLazyByteString (这太慢了)。

是否可以在不先将 Builder 转换为 ByteString 的情况下获取其长度?

或者,是否有另一种方法(有效地)实现制表(使用或不使用Builder)?

最佳答案

调查 Builder 的来源,其定义为

newtype Builder = Builder (forall r. BuildStep r -> BuildStep r)

所以排序Builder只是组合函数,并且无法在不评估函数堆栈的情况下获取输出的长度。但是您可以使用将 Builder 与长度计算结合起来的数据类型创建自己的帮助器模块:

newtype BuilderL = BuilderL { blLenght :: !Int, blBuilder :: Builder }

instance Monoid BuilderL where
    mempty = BuilderL 0 mempty
    mappend (BuilderL l1 t1) (BuilderL l2 t2) = BuilderL (l1 + l2) (t1 <> t2)

然后创建用于构造 BuilderL 的辅助函数,例如

byteString :: ByteString -> BuilderL
byteString t = BuilderL (length t) (byteString t)

等等。然后将此模块和 BuilderL 用于您的表格,您将始终掌握所需的长度。

关于haskell - 获取 Data.ByteString.Builder 的长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26492205/

相关文章:

haskell - 为什么这个类型注释是错误的?

haskell - 简单数据类型的未装箱向量

Haskell 列表递归 - 为什么一个有效而另一个无效?

haskell - Repa 2 和 3 API 之间的主要区别是什么?

Haskell - 奇怪的阻止行为

haskell - 在 Haskell 中编写带条件的递归函数 :

haskell - 如何使用 Criterion 来衡量 Haskell 程序的性能?

haskell - 使用 Cabal (Haskell) 从环境变量控制 GHC 构建选项

haskell - 我可以说服 stack/ghci *仅*加载本地 .ghci 文件吗?

haskell - 如何将 DiffTime 转换为 NominalDiffTime?