Several default implementations for instance methods

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@gu.se http://www2.tcs.ifi.lmu.de/~abel/

hrm, so youre wanting something even smarter than the MINIMAL pragma stuff,
namely
"depending on which subset of the complementary methods are defined, define
this method differently"?
On Sat, Oct 4, 2014 at 11:44 AM, Andreas Abel
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@gu.se http://www2.tcs.ifi.lmu.de/~abel/ _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Sat, Oct 4, 2014 at 12:05 PM, Carter Schonwald < carter.schonwald@gmail.com> wrote:
hrm, so youre wanting something even smarter than the MINIMAL pragma stuff, namely "depending on which subset of the complementary methods are defined, define this method differently"?
I've been expecting someone to ask for that ever since MINIMAL was floated.... (In fact I more than half expected MINIMAL to vanish under a bikeshed with that as its frame.) -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
participants (3)
-
Andreas Abel
-
Brandon Allbery
-
Carter Schonwald