Several default implementations for instance methods
Andreas Abel
abela at chalmers.se
Sat Oct 4 15:44:28 UTC 2014
Consider the following class for an overloaded pretty printer. For
atomic data (numeric types, String etc.) one would implement
prettyShow, for complex data either pretty or prettyPrec.
> import Text.PrettyPrint
>
> class Pretty a where
> pretty :: a -> Doc
> prettyShow :: a -> String
> prettyPrec :: Int -> a -> Doc
Implementing one of these methods should be enough, giving default
implementations for the other two.
It is easy to get prettyShow and prettyPrec from pretty.
> prettyShow = render . pretty
> prettyPrec = const . pretty
However, to define pretty from one of the others, I need two default
implementations.
> pretty = text . prettyShow
> pretty = prettyPrec 0
Is there a way to get this to work?
Workarounds (not entirely satisfactory): Technically, one could define
a cycle of default implementations. Alternative 1:
> pretty = prettyPrec 0
> prettyShow = render . pretty
> prettyPrec _ = text . prettyShow
Problem: Here, if pretty is defined,
> prettyPrec _ = text . render . pretty
instead of just
> prettyPrec _ = pretty
and (text . render) is not the identity (destroys inner document structure).
Alternative 2:
> pretty = text . prettyShow
> prettyShow = render . prettyPrec 0
> prettyPrec _ = pretty
Problem: Here, if prettyPrec is defined,
> pretty = text . render . prettyPrec 0
instead of just
> pretty = prettyPrec 0
I guess alternative 2 is worse than alternative 1, as one would
usually define prettyPrec to get pretty, and not the otherway round.
But none of these two alternatives really does the job.
--
Andreas Abel <>< Du bist der geliebte Mensch.
Department of Computer Science and Engineering
Chalmers and Gothenburg University, Sweden
andreas.abel at gu.se
http://www2.tcs.ifi.lmu.de/~abel/
More information about the Haskell-prime
mailing list