Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is the instance of Show for String written?

I have a basic question about definining instances of typeclasses. I am using the Show typeclass as an example, and I am considering only the function show within the class. The Show instance for a concrete type like Bool is simple

instance Show Bool where
  show x = {function of x here}

but for String it is not:

instance Show String where
  show x = {function of x here}

produces understandably an error

Illegal instance declaration for ‘Formatter String’
  (All instance types must be of the form (T t1 ... tn)
   where T is not a synonym.
   Use TypeSynonymInstances if you want to disable this.)
In the instance declaration for ‘Formatter String’

and of course the following is not allowed:

instance Show [Char] where
  show x = {function of x here}

I could define a newtype

newtype String2 = String2 String 
instance Formatter String2 where
  format (String2 x) = {function of x here}

which however does not allow me to do show "test", as I am able to do in Haskell.

What essential feature of typeclasses am I missing?

like image 995
gappy Avatar asked Jan 14 '15 20:01

gappy


1 Answers

The Show typeclass actually has three member functions, show, showsPrec, and showList. In the instance for Show Char, the showList function is overloaded to output quote marks and shove all the letters together without delimiters:

From GHC.Show:

instance  Show Char  where
    showsPrec _ '\'' = showString "'\\''"
    showsPrec _ c    = showChar '\'' . showLitChar c . showChar '\''

    showList cs = showChar '"' . showLitString cs . showChar '"'

Where showLitString is defined as:

showLitString :: String -> ShowS
-- | Same as 'showLitChar', but for strings
-- It converts the string to a string using Haskell escape conventions
-- for non-printable characters. Does not add double-quotes around the
-- whole thing; the caller should do that.
-- The main difference from showLitChar (apart from the fact that the
-- argument is a string not a list) is that we must escape double-quotes
showLitString []         s = s
showLitString ('"' : cs) s = showString "\\\"" (showLitString cs s)
showLitString (c   : cs) s = showLitChar c (showLitString cs s)

So there is no Show String instance, it's simply that Show Char defines how to call show on [Char] values specifically.

like image 97
bheklilr Avatar answered Sep 17 '22 18:09

bheklilr