Derived Show and Read

Sigbjorn Finne sof@galois.com
Thu, 11 Apr 2002 12:53:12 -0700


That looks fine, I've updated Hugs to comply.

However, the example you give in bullet 2 doesn't
make sense - I suspect you want to say

infixr :$
data T = Int :$ Int | T Int

* "show (1 :$ 2 :$ T 3)" produces the string "1 :$ (2 :$ (T 3))"
...

or some such.

In the style of Haskell-1.2 (and earlier) informal spec. of the
derived Show instance, Hugs now implements the following:

  showsPrec d (e1 `Con` e2) = showParen (d > p) showStr
    where
      showStr = showsPrec lp e1 . showChar ' ' .
                       showString cn    . showChar ' ' .
                       showsPrec rp e2
      p   = 'the precedence of Con'
      lp  = p+1
      rp  = p+1
      cn  = 'the original name of Con'

similarly for Read.

Was there a good technical reason for dropping that portion of
the Report (1.3 onwards), btw? Preferable to bulleted text, IMHO.

--sigbjorn

----- Original Message -----
From: "Simon Peyton-Jones" <simonpj@microsoft.com>
To: <Malcolm.Wallace@cs.york.ac.uk>; <sof@galois.com>; <jeff@galconn.com>;
<hugs-bugs@haskell.org>
Cc: <simonmar@microsoft.com>; "Simon Peyton-Jones" <simonpj@microsoft.com>
Sent: Tuesday, April 09, 2002 06:04
Subject: Derived Show and Read


> Malcolm, Huggers,
>
> Olaf points out that the defn of derived instances of Read
> in the H98 appendix isn't right.  In particular, to avoid
> problems we should require parentheses when the precedence
> level doesn't change, even if the associativity could in principle
> let us do without.
>
> I propose to replace the first set of bullets in D.4 with the
> following, and change the example code to match.  (I think I'll make
> the constructor infixr, just to make the point.)
>
> [This replaces my earlier proposal to change 'less than' to
> 'less than or equal to'.]
>
> This change will affect Hugs and nhc: in particular, 'Show' should
> output parentheses even if associativity might allow them to
> be omitted.
>
> Before enshrining this change I wanted to check that it looks
> reasonable to you.  RSVP
>
> Simon
>
> ========================
>
> "Derived instances of Read make the following assumptions,
> which derived instances of Show obey:
>
> 1.  If the constructor is defined to be an infix operator, then the
> derived Read instance will parse only infix applications of the
> constructor (not the prefix form).
>
> 2. Associativity is not used to reduce the occurrence of
> parentheses, although precedence may be. For example, given
> infixr :$
> data T = Int :$ Int
> then:
>   *   "show (1 :$ 2 :$ 3)" produces the string "1 :$ (2 :$ 3)".
>   *   (read "1 :$ (2 :$ 3)") succeeds, with the obvious result.
>   *   (read "1 :$ 2 :$ 3") fails.
>
>
> 3.  Similarly, if the constructor is defined using record syntax, the
> derived Read will parse only the record-syntax form, and furthermore,
> the fields must be given in the same order as the original
> declaration.
>
> 4.  The derived Read instance allows arbitrary Haskell whitespace
> between tokens of the input string.  Extra parenthese are also
> allowed."
>
>
> Outside the bullets I'll collect the stuff about Show:
>
> "The result of @show@ is a syntactically correct \Haskell{} expression
> containing only constants, given the fixity declarations in force at
> the point where the type is declared.  It contains only the
> constructor names defined in the data type, parentheses, and spaces.
> When labelled constructor fields are used, braces, commas, field
> names, and equal signs are also used.  Spaces and parentheses are only
> added where needed, ignoring associativity.  No line breaks are added.
> The result of @show@ is readable by @read@ if all component types are
> readable.  (This is true for all instances defined in the Prelude but
> may not be true for user-defined instances.)"
>