List comprehensions (or ZF-expressions) include a sequence of qualifiers, which can be generators or Boolean-valued expressions ("filter expressions") acting as guards.
A list comprehension with no qualifier – for instance, [1 | ]
– is (apparently) valid in Miranda1 (p. 130), but is invalid in Haskell2, 3 (p. 42) –I tried it in the ghci
interpreter– and is (apparently) invalid in Clean4.
(Of course, we could simulate it by adding a True
guard, for instance [1 | True]
. But this is more verbose.)
An example of use of a list comprehension with no qualifier in the literature1 (pp. 134-136) is the following instance of equational reasoning:
[E | ] ++ L = [E] ++ L = (E:[]) ++ L = E:L
Why did Haskell and Clean programming language designers decide against list comprehensions without qualifiers? Is there something that would cause bad feature interactions in these languages but not in Miranda?
References:
Simon L. Peyton Jones. The Implementation of Functional Programming Languages. Prentice Hall. 1987.
The Haskell 98 Report, section 3.11 "List Comprehensions". 1998.
Peter Wentworth. An Introduction to Functional Programming Using Hugs. 2013.
Rinus Plasmeijer; Marko van Eekelen; John van Groningen. Clean Language Report, version 2.2. 2011.
I think the obvious answer is that there is no technical reason to disallow list comprehensions with an empty sequence of qualifiers. The requirement is a purely syntactic one. It just so happens that the original Haskell98 report section 3.11 specifies a grammar that requires the list of qualifiers to be non-empty, and the translation rules to turn it into a kernel expression assume this is the case. GHC obeys this grammar, so an expression like
[ 10 | ]
is rejected with a parse error.From a technical standpoint, simply relaxing the grammar and adding a single translation rule:
would address this.
In fact, the documentation for the GHC
MonadComprehensions
extension actually provides a translation for this case:and the rest of the translation rules basically assume that cases of the form:
apply to the special case:
with
Q
taken to be empty.Once you get past the parser, the rest of GHC handles this special case just fine. In particular, if you use Template Haskell to bypass the parser and construct a comprehension with no qualifiers, you can see that it evaluates as expected. (The separate modules here are needed because of the TH phase restricution.)
As for why the language was designed this way, I imagine it was either an oversight or perhaps it was considered at some point but the syntax
[10 | ]
was thought to be too bizarre to allow.On a related note, empty
case
s were also disallowed by the original Haskell98 report but then permitted via anEmptyCase
extension when it was discovered that they could actually be useful.I think you might have trouble convincing anyone that a similar extension for comprehensions is worthwhile. In the comments, you mention automatic source generation, but it's easy to handle that case specially or add an extra
True
qualifier to every comprehensive (or -- if you're generating source via TemplateHaskell -- just bypass the restriction directly).