【问题标题】:Text.PrettyPrint a better way to set indentationText.PrettyPrint 设置缩进的更好方法
【发布时间】:2012-11-10 09:16:11
【问题描述】:

我有一台这样漂亮的打印机:

somefun = text "woo" $+$ nest 4 (text "nested text") $+$ text "text without indent"
fun = text "------" $+$ somefun

我想要的是打印这个:

------ woo
    nested text
text without indent

但它会打印:

------
woo
    nested text
text without indent

我可以理解为什么会这样打印,但是我无法按照自己的意愿去做。我找到的一种解决方案是:

somefun p = p <+> text "woo" $+$ nest 4 (text "nested text") $+$ text "text without indent"
fun = somefun (text "------")

也就是说,我正在传递我希望下一个 Doc 的缩进所基于的 Doc。这解决了我的问题,但我正在寻找更好的方法来做到这一点。

【问题讨论】:

  • 我不认为有更好的方法,somefunDoc,这被认为是一个块,你不能在事后只拔出第一行然后改变它。

标签: haskell pretty-print


【解决方案1】:

您的将文档作为参数传递的解决方案很好。一旦组合成一个 Doc,就不能再拆分,所以这里有两种使用列表的方法:

备选方案 1

另一种方法是在后续文本中使用[Doc] 而不是Doc,如果您想以不同的方式处理这些行,则使用类似的东西重新组合

(<+$) :: Doc -> [Doc] -> Doc
doc <+$ [] = doc 
doc <+$ (d:ds) = (doc <+> d) $+$ foldr ($+$) empty ds

somefun :: [Doc]
somefun = [text "woo",
    nest 4 (text "nested text"),
    text "text without indent"]

fun :: Doc
fun = text "------" <+$ somefun

这给了你

*Main> fun
------ woo
    nested text
text without indent

备选方案 2

如果你想继续缩进第一行,你可以用另一种保持列表的方式重写这个解决方案:

(<+:) :: Doc -> [Doc] -> [Doc]
doc <+: [] = [doc] 
doc <+: (d:ds) = (doc <+> d) : ds -- pop doc in front.

我们需要在某个阶段将它们组合成一个 Doc

vsep = foldr ($+$) empty

现在你可以用:在上面放一行,用&lt;+:在顶行前面推一点:

start = [text "text without indent"]
next  = nest 4 (text "nested text") : start
more  = text "woo" : next
fun   = text "------" <+: more
extra = text "-- extra! --" <+: fun

用这个测试一下

*Main> vsep fun
------ woo
    nested text
text without indent

*Main> vsep extra
-- extra! -- ------ woo
    nested text
text without indent

主要问题是,如果您使用[Doc] 而不是Doc,就好像您没有使用漂亮打印库一样!不过没关系,如果它是你需要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    • 1970-01-01
    • 2012-11-11
    • 2011-10-21
    相关资源
    最近更新 更多