automatic instances for pretty printing and parsing
Dear all, I use Text.PrettyPrint.HughesPJ and Text.ParserCombinators.Parsec heavily so I made some DrIFT rules for deriving the "obvious" instances for class ToDoc a where toDoc :: a -> Doc class Reader a where readerPrec :: Int -> Parser a http://141.57.11.163/cgi-bin/cvsweb/drift/src/UserRuleToDoc.hs?rev=1.5 Still I'd like to avoid external preprocessors (for hygienic reasons, and because they do not seem to fit well with the Cabal model) so I'd like to investigate whether I could get the same effect with Template Haskell (in ghc) - and what this would cost. Perhaps someone has solved a similar problem before. On the other hand, HaXml does need DrIFT it seems. -- -- Johannes Waldmann -- Tel/Fax (0341) 3076 6479/80 -- ---- http://www.imn.htwk-leipzig.de/~waldmann/ -------
Hello Johannes, Tuesday, October 04, 2005, 4:26:27 PM, you wrote: JW> I use Text.PrettyPrint.HughesPJ and JW> Text.ParserCombinators.Parsec heavily so I made JW> some DrIFT rules for deriving the "obvious" instances for JW> so I'd like to investigate whether I could get the same effect JW> with Template Haskell (in ghc) - and what this would cost. well, it is not so pretty, but it works :) try "ghc --make -ddump-splices test-derive.hs" i wrote this to include in doc as an example of using reification facilities, so if it can be simplified or better documented - say to me :) -- Best regards, Bulat mailto:bulatz@HotPOP.com
Johannes Waldmann wrote:
I use Text.PrettyPrint.HughesPJ and Text.ParserCombinators.Parsec heavily so I made some DrIFT rules for deriving the "obvious" instances for
class ToDoc a where toDoc :: a -> Doc class Reader a where readerPrec :: Int -> Parser a
Perhaps someone has solved a similar problem before.
I was looking for the same thing because I didn't like the way derived instances of Read depend on whether I define my datatypes in prefix, infix or record form. I ended up writing my own Read derivation using Template Haskell. Here it is. Basically it can read prefix, infix or record syntax where applicable. It is based on ReadPrec, not Parsec though. Some further notes and questions: 1. Instead of Read I actually use another class, Parse, which is a clone of Read. The reason is that I wanted to have new instances for some standard types that already have their Read instances defined. This introduces some hackery and requires you to use -fallow-overlapping-instances. If you don't like it, it should be quite easy to go back to Read. 2. My instance context derivation is very primitive: I simply repeat all the field types in the context, say
data T a b = T1 Int | T2 (a b) (Maybe b) instance (Parse Int, Parse (a b), Parse (Maybe b)) => Parse (T a b)
The result is that you need -fallow-undecidable-instances to chew through all that :) Here a question: are there any pitfalls about writing such instances that I don't currently see? Any feedback, improvements, fixes, etc. always welcome! Cheers, Misha
participants (3)
-
Bulat Ziganshin -
Johannes Waldmann -
Misha Aizatulin