Pretty class as alternative for Show class

There seems to be the need for (at least) two classes for showing values in Haskell: One class that outputs values in a way that can be copied and pasted into Haskell programs. This is useful in GHCi. Another class (say Pretty) that shows values in a prettily formatted way. Current libraries use the Show class for both applications depending on the taste of the author. A third class would be useful for outputting values with markup, say HTML or LaTeX. The Show class converts to String, the Pretty class could convert to a pretty printer data type like Doc. The Show class should output all data that is necessary to reconstruct the value, but not necessarily in the form of the underlying data structure, but maybe using appropriate generating functions. Thus e.g. 'show' for Doubles does not need a parameter for precision, it just emits all available digits. On the other hand a Pretty class should have such parameters (maybe then requiring a multi-parameter type class with functional dependency from value type to formatting style type). A nice infix operator like (//) like in the GSL wrapper could flatten the Pretty data to String, and thus is easy to use in GHCi. Matrix> fiboMatrix matrix [[1,0], [1,1]] Matrix> fiboMatrix // 3 /1.000 0.000\ \1.000 1.000/ where (//) :: Pretty style value => value -> style -> IO String x // p = putStr (Doc.toString (Pretty.toDoc p x)) class Pretty style value | value -> style where toDoc :: style -> value -> Doc If such a separation would become consensus then libraries could better separate the concerns of pretty output and re-usable output.

Henning Thielemann wrote:
The Show class converts to String, the Pretty class could convert to a pretty printer data type like Doc. [...]
Ah yes, I use this since a long time class ToDoc a where toDoc :: a -> Doc toDoc = toDocPrec 0 -- useful? toDocPrec :: Int -> a -> Doc http://141.57.11.163/cgi-bin/cvsweb/lib/Autolib/ToDoc/ I generally make even this output re-readable, and I'm reading is via Parsec: class Reader a where readerPrec :: Int -> Parser a http://141.57.11.163/cgi-bin/cvsweb/lib/Autolib/Reader/ and I also have the obvious DrIFT rules that can generate standard instances for most types. http://141.57.11.163/cgi-bin/cvsweb/drift/src/UserRuleToDoc.hs?rev=1.7 http://141.57.11.163/cgi-bin/cvsweb/drift/src/UserRuleReader.hs?rev=1.6 I will happily contribute this code to whatever Pretty class emerges. (Well, it's free, so I'd have no way to not contribute it ...) best regards, Johannes.

On Feb 13, 2008 7:45 AM, Henning Thielemann
There seems to be the need for (at least) two classes for showing values in Haskell: One class that outputs values in a way that can be copied and pasted into Haskell programs. This is useful in GHCi. Another class (say Pretty) that shows values in a prettily formatted way. Current libraries use the Show class for both applications depending on the taste of the author. A third class would be useful for outputting values with markup, say HTML or LaTeX.
I've started to do this for my own code now. I use Show as an equivalent of Python's 'repr' and pretty for displaying things to users. -- Johan

See my 'Doc' project. which includes both a show alternative class like you describe as well as a class abstracting different pretty printers. http://repetae.net/repos/Doc I use it in quite a few of my projects and it has served me well. John -- John Meacham - ⑆repetae.net⑆john⑈

On Wed, 13 Feb 2008, John Meacham wrote:
See my 'Doc' project. which includes both a show alternative class like you describe as well as a class abstracting different pretty printers.
I use it in quite a few of my projects and it has served me well.
It seems like it was a good idea for me to ask. - What about uploading all three packages to Hackage (Johannes Waldmann's, Johan Tibell's and John Meacham's - the package idea seems to be related to the first name :-) and propose them as addition to the standard Show class? It would help people to convince no to abuse the Show class for pretty printing.

On Feb 13, 2008 2:15 PM, Henning Thielemann
It seems like it was a good idea for me to ask. - What about uploading all three packages to Hackage (Johannes Waldmann's, Johan Tibell's and John Meacham's - the package idea seems to be related to the first name :-) and propose them as addition to the standard Show class? It would help people to convince no to abuse the Show class for pretty printing.
My Pretty class is exactly the same as the Show class (i.e. returns a String). I just want two versions of the same thing. It's like Python's repr and str. Both returns strings but with different purposes. Relying on a pp library is often too heavyweight for my needs. -- Johan

John Meacham wrote:
See my 'Doc' project. which includes both a show alternative class like you describe as well as a class abstracting different pretty printers.
Why should I use your DocLike module (instead of Text.PrettyPrint.HughesPJ directly)? from module DocLike: x <+> y = x <> char ' ' <> y x <$> y = x <> char '\n' <> y encloseSep l r s ds = enclose l r (hcat $ punctuate s ds) enclose l r x = l <> x <> r list = encloseSep lbracket rbracket comma tupled = encloseSep lparen rparen comma semiBraces = encloseSep lbrace rbrace semi 1. The indentation is wrong for Doc from your module Pretty (and strings): *Pretty> text "a" DocLike.<+> (text "b" DocLike.<$> text "c") :: Doc a b c 2. encloseSep may produce too long lines without breaks The HughesPJ output is correct: *DocLike> P.text "a" <+> (P.text "b" <$> P.text "c") a b c Cheers Christian

On Wed, Feb 13, 2008 at 03:01:21PM +0100, Christian Maeder wrote:
John Meacham wrote:
See my 'Doc' project. which includes both a show alternative class like you describe as well as a class abstracting different pretty printers.
Why should I use your DocLike module (instead of Text.PrettyPrint.HughesPJ directly)?
Because then the same code will work with any of the pretty printers out there, Strings, and ShowS directly. It is an abstract type. I also have ones that spit out html and one that spits out ascii text along with a function that goes from screen position to what was used to create it so you can find out what people clicked a mouse on.
from module DocLike:
x <+> y = x <> char ' ' <> y x <$> y = x <> char '\n' <> y encloseSep l r s ds = enclose l r (hcat $ punctuate s ds) enclose l r x = l <> x <> r list = encloseSep lbracket rbracket comma tupled = encloseSep lparen rparen comma semiBraces = encloseSep lbrace rbrace semi
1. The indentation is wrong for Doc from your module Pretty (and strings):
*Pretty> text "a" DocLike.<+> (text "b" DocLike.<$> text "c") :: Doc a b c
2. encloseSep may produce too long lines without breaks
The HughesPJ output is correct:
*DocLike> P.text "a" <+> (P.text "b" <$> P.text "c") a b c
This is simply due to the underlying implementation you are using, there are many instances, you should get exactly the same results as you do with HughesPJ if you use the HughesPJ instance as it is what is used to do the formatting. It is possible however that I did not override all the needed methods for the HughesPJ instance as I more often use a modified version of Daan's parser that can handle things like html and ansi color codes so might not have noticed if I forgot one. those are only default implementations, suitable for things like 'String' or 'ShowS', it is expected instances that use a real back end would override them with more interesting things. John -- John Meacham - ⑆repetae.net⑆john⑈

John Meacham wrote:
The HughesPJ output is correct:
*DocLike> P.text "a" <+> (P.text "b" <$> P.text "c") a b c
Could Daan's parser (that I only looked at) create such "correct" output, too?
I more often use a modified version of Daan's parser that can handle things like html and ansi color codes so might not have noticed if I forgot one.
I would like to combine the advantages of HughesPJ (above) and Daan's parser (including soft breaks). Cheers Christian

On Thu, Feb 14, 2008 at 09:56:15AM +0100, Christian Maeder wrote:
John Meacham wrote:
The HughesPJ output is correct:
*DocLike> P.text "a" <+> (P.text "b" <$> P.text "c") a b c
Could Daan's parser (that I only looked at) create such "correct" output, too?
I believe so, I generally use daan's because I find it easier to create good layout in and i think it is strictly more powerful. I didn't try to hard to match up the operators exactly between the two instances but I probably should, as I didn't use the hughespj one much. it is likely I can get them to produce the same results with some tweaking and I might want to add a couple more forms of line break into the class. here is a link to his paper on his pretty printer http://citeseer.ist.psu.edu/480959.html -- John Meacham - ⑆repetae.net⑆john⑈

John Meacham wrote:
Because then the same code will work with any of the pretty printers out there, Strings, and ShowS directly. It is an abstract type. I also have ones that spit out html and one that spits out ascii text along with a function that goes from screen position to what was used to create it so you can find out what people clicked a mouse on.
Browsers break html-code for you, but the most important part (namely to compose vertically if horizontally does not fit into the width) is missing from your DocLike class. (Producing strings is no problem for any pretty printer library.) Christian
participants (5)
-
Christian Maeder
-
Henning Thielemann
-
Johan Tibell
-
Johannes Waldmann
-
John Meacham