我有一个函数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
在每个元素上(这太慢了)。
是否可以得到a的长度Builder
无需先将其变成ByteString
?
或者,是否有另一种方法(有效)实现tabulate
(使用或不使用Builder
)?
探究源头Builder http://hackage.haskell.org/package/bytestring-0.10.2.0/docs/src/Data-ByteString-Builder-Internal.html#Builder,它被定义为
newtype Builder = Builder (forall r. BuildStep r -> BuildStep r)
所以测序Builder
只是组合函数,并且在不评估函数堆栈的情况下无法获取输出的长度。但是您可以创建自己的辅助模块,其数据类型将结合Builder
s 与长度计算:
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
s, like
byteString :: ByteString -> BuilderL
byteString t = BuilderL (length t) (byteString t)
等等,然后使用这个模块并BuilderL
适合您的桌子,并且您始终可以掌握所需的长度。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)