我有一台漂亮的打印机:
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缩进基于。这解决了我的问题,但我正在寻找更好的方法来做到这一点。
答案 0 :(得分:2)
你传递的Doc-as-an-argument解决方案很好。一旦你合并到一个Doc中,就不能再将它拆分,所以这里有两种使用列表的方式:
另一种方法是使用[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
如果你想保持缩进顶线,你可以用另一种方式重写这个解决方案:
(<+:) :: 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
,那就好像您没有使用漂亮的打印库一样!但是,如果这是你需要的,那没关系。