This is a suggestion for a more orthogonal list syntax. When I was using
list comprehensions recently, the following happened to me: I wanted to
do something like a map over a list, but the result should contain *two*
members for every member of the argument list. Of course, this can be
written as

  [x | y <- someList, x <- [f y, g y]].

But wouldn't

  [f y, g y | y <- someList]

be much nicer and easier to read? Such a syntax is also usual for set
abstractions in mathematics. So I suggest to allow arbitrary
enumerations of expressions to the left of the "|" in comprehensions.

A similar example: Assume you have a list of intervals given as pairs of
integers, and you want to compute the list of integers within the
intervals. Today you have to write:

  [i | (from, to) <- intervals, i <- [from..to]]

But the following is certainly nicer:

  [from..to | (from, to) <- intervals]

For even more orthogonality, I suggest that *anything* that is allowed
between brackets (i.e., nothing for the empty list, comma-separated
expressions for explicitly enumerated lists, "exp1 [, exp2] .. [exp3]"
for arithmetic sequences, and even the stuff needed for a comprehension)
should also be allowed to the left of the "|" in a comprehension. (One
might be less radical here, but why should there be any restrictions?)

The change is formalized by the following modifications in section 3 of
the Haskell-1.4 report:

1. Remove the case `[]' from `gcon'.

2. Replace the cases
   - `[ exp1 , ... , expk ]',
   - `[ exp1 [, exp2] .. [exp3] ]',
   - `[ exp | qual1 , ... , qualn ]', and
   of `aexp' by the single case `[ listContent ]'.

3. Replace the case `[ pat1 , ... , patk ]' of `apat' by
   `[ [pat1 , ... , patk] ]'.

4. Define `listContent' as:

   listContent -> {- nothing -}                      (empty list)
               |  exp1 , ... , expk                  (enumerated list, k>=2)
               |  exp1 [, exp2] .. [exp3]            (arithmetic sequence)
               |  listContent | qual1 , ... , qualn  (list comprehension, n>=1)

5. The first equation in the translation for list comprehensions becomes:

     [ lc | q1, ..., qn ] = do { T(q1); ...; T(qn); e <- [ lc ] ; return e }

(If you find it hard to find out whether a bracket, a sequence of dots,
or a vertical bar belongs to the grammar notation or to the described
syntax: The same holds for the report already now.)

Does this suggestion make sense?

I think the change is quite simple and I don't see any possibly harmful
implications, so it might even go into Haskell98. But I also understand
that it is already quite late in 1998.

Regards,
Heribert.


PS: Note that this syntax extension would not make sense for arbitrary
monad comprehensions. But comprehensions have been restricted to lists
anyway.

PPS: If the same symbol "," were not used both in enumerated lists and
in arithmetic sequences, then one might even allow that any expi in an
enumeration is actually an arithmetic sequence without the brackets.
This would make the syntax even more flexible. Nevertheless I don't
propose this modification.


Reply via email to