0

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

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

4

1 回答 1

2

您将文档作为参数传递的解决方案很好。一旦组合成一个 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它几乎就像你没有使用漂亮打印库一样!不过没关系,如果它是你需要的。

于 2012-11-10T17:29:03.000 回答