获取Data.ByteString.Builder的长度 [英] Getting the length of a Data.ByteString.Builder

查看:113
本文介绍了获取Data.ByteString.Builder的长度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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



是否有可能获得没有首先将 ByteString


$ b $作为 Builder 的长度b

或者,是否有另一种方式(有效)实现 tabulate (使用或不使用 Builder )?

解决方案

寻找 Builder ,它被定义为

  newtype Builder = Builder(Forall r。BuildStep r  - > BuildStep r)
pre>

因此,排序 Builder 只是组合函数,并且没有办法如何获得输出的长度而无需评估功能堆栈。但是你可以用一个数据类型创建你自己的帮助模块,这个数据类型可以结合 Builder s和长度计算:

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

实例Monoid BuilderL其中
mempty = BuilderL 0 mempty
mappend (BuilderL l1 t1)(BuilderL l2 t2)= BuilderL(l1 + l2)(t1≠t2)

然后创建帮助函数来构造 BuilderL s,比如

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

等。然后使用这个模块和 BuilderL 作为你的表格,你将始终拥有这个长度。


I have a function tabulate that takes a list of objects, and a list of functions that turn fields of these objects into Builders. It returns a Builder representing a nicely formatted table. E.g.:

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

To do this I need to determine the maximum length for each column. At the moment I am using toLazyByteString on each element (which is too slow).

Is it possible to get the length of a Builder without first turning it into a ByteString?

Alternatively, is there another way to (efficiently) implement tabulate (with or without using Builder)?

解决方案

Looking into the source of Builder, it's defined as

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

So sequencing Builder is just composing functions, and there is no way how to get the length of the output without evaluating the stack of functions. But you could create your own helper module with a data type that would combine Builders with length calculations:

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)

and then create helper functions for constructing BuilderLs, like

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

etc. Then use this module and BuilderL for your tables and you'll always have the length at hand.

这篇关于获取Data.ByteString.Builder的长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆