| I'm fairly sure that local definitions were possible in Miranda(TM), and
| I see they are permitted in Gofer. Mark Jones explains why they are not
| part of Haskell, on page 44 of the Gofer manual:
|
| Local definitions: A qualifier of the form pat = expr [...]
|
| [ e | pat = exp ] = [ let pat=exp in e ]
|
| [...] There was a certain amount of controversy surrounding the
| choice of an appropriate syntax and semantics for the construct
| and consequently, this feature is not currently part of the
| Haskell standard.
|
| I'm sorry if, by being new to this list, I have missed discussion about
| this issue, but could somebody briefly explain the `controversy'?
As I recall, there were three points of disagreement:
- syntax ... would pat=exp be confused with pat==exp, for example?
- semantics ... should pat=exp be a standard recursive binding,
with [e | pat=exp] an alternative notation for [let pat=exp in e]?
Or should it just be an abbreviation for the (non-recursive) binding:
pat<-[exp]? There's also the question that Kevin raised about what
to do when a local definition pattern match fails. i.e. deciding
whether [ 1 | [x] = [1,2] ] should be bottom or [].
- necessity ... Haskell already has two ways (at least) to introduce
local definitions. Some people were concerned that a third form of
local definition was unnecessary.
| has it now been resolved, i.e., will local definitions in list compre-
| hensions be defined in Haskell 1.3?
I don't know. However, the passage of the Gofer manual that you quoted above
is pretty old. There are some more recent comments in the release notes for
2.28. A summary is that:
- Yes, people do get confused by the similarity between `==' and `='.
My preferred syntax is let '{' decls '}'. This allows multiple
line function definitions etc. if that generality is ever wanted.
Perhaps it won't be used that often for list comprehensions, but it
certainly is useful for monad comprehensions.
- As before, I prefer the recursive binding semantics for consistency
with the rest of the language:
[ e | let { decls } ] = [ let { decls } in e ]
- Local definitions in list comprehensions are not necessary. But they
are often useful.
Kevin has already commented:
| Apart from choosing the right syntactic form (a relatively minor issue),
| there should be nothing controversial about such comprehensions.
| They add expressive power at almost zero implementation cost (my
| original implementation added one significant line to a 20000 line
| compiler). I don't know how the other Haskell 1.3ers feel about these?
The implementation in Gofer was a little more complicated than this because
the translation of list comprehensions is postponed until after static
analysis type checking etc. As a result, extra code is needed, for example,
to type check local definitions in a list comprehension. However, it was
still a relatively simple task to add this feature and, in my opinion, well
worth the time I spent on it.
All the best,
Mark