Text.PrettyPrint是设置缩进的更好方法

时间:2012-11-10 09:16:12

标签: haskell pretty-print

我有一台漂亮的打印机:

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缩进基于。这解决了我的问题,但我正在寻找更好的方法来做到这一点。

1 个答案:

答案 0 :(得分:2)

你传递的Doc-as-an-argument解决方案很好。一旦你合并到一个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

现在,您可以使用:在上方添加一行,并<+:在顶行前面稍微推动一下:

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,那就好像您没有使用漂亮的打印库一样!但是,如果这是你需要的,那没关系。