Suppose I have this data type:
data SomeDataType a = SomeDataType a
I want to show my presentation to the user (at the output of the console), so I need the function "pretty printed". I don't want to use showit because it will return an expression, and I just want the value of a field of my type to be converted to a string.
I expect this behavior:
>>> let myintdata = SomeDataType (22::Int)
>>> putStrLn $ prettyPrint myintdata
22
>>> let alice = SomeDataType "Alice"
>>> let bob = SomeDataType "Bob"
>>> putStrLn $ prettyPrint alice ++ " loves " ++ prettyPrint bob
Alice loves Bob
So, I implement it as follows:
prettyPrint :: Show a => SomeDataType a -> String
prettyPrint (SomeDataType x) = show x
It works fine for numbers, but strings are quoted and escaped:
>>> let alice = SomeDataType "Alice"
>>> let bob = SomeDataType "Bob"
>>> putStrLn $ prettyPrint alice ++ " loves " ++ prettyPrint bob
"Alice" loves "Bob"
In addition, I want full control over how various types of content are converted to strings in the future. So, I want to create my own class. This happens as follows:
{-# LANGUAGE FlexibleInstances #-}
data SomeDataType a = SomeDataType a
class PrettyPrint a where
prettyPrint :: a -> String
instance {-# OVERLAPPABLE #-} PrettyPrint a where
-- I don't care about this right now,
-- let learn how to print strings without quotes first!
prettyPrint = const "Stupid Robot"
instance PrettyPrint String where
prettyPrint = id
instance Show a => PrettyPrint (SomeDataType a) where
prettyPrint (SomeDataType x) = prettyPrint x
I am pleased with the first test:
>>> putStrLn $ prettyPrint "No quotes!"
No quotes!
, String - :
>>> let alice = SomeDataType "Alice"
>>> let bob = SomeDataType "Bob"
>>> putStrLn $ prettyPrint alice ++ " loves " ++ prettyPrint bob
Stupid Robot loves Stupid Robot
, " ". ? ?