Proposal: fix "simple pattern binding" and "declaration group"

dm-list-haskell-prime at dm-list-haskell-prime at
Mon Jun 27 04:46:00 CEST 2011

At Mon, 27 Jun 2011 00:06:09 +0100,
Paterson, Ross wrote:
> I don't believe the definition of "depends" in Section 4.5.1 needs
> to change. The Report consistently uses "expression type signature"
> for the expression and "type signature" for the declaration, so it is
> clear that the latter is meant here.

Okay, but what about at least adding a couple of examples of
declaration groups?  The Haskell98 report is very clear about what a
declaration group is.  The 2010 report definition is extremely terse
and borderline ambiguous.

Even if the report is 90% consistent about using the term "expression
type signature", it is not 100% consistent and more importantly never
explicitly says that in the absence of the word "expression", the term
"type signature" always means declaration type signature when both
readings make sense.

A reader could reasonably expect that a phrase such as "an expression
with an expression type signature" might sometimes be shortened to "an
expression with a type signature" when it is clear one is talking
about expression type signatures.  For example, section 3.13 ends with
the note:

        case x of { (a,_) | let b = not a in b :: Bool -> a }

	... Programmers are advised, therefore, to avoid guards that
	end with a type signature.

The example inspiring this advice clearly contains an expression type
signature, not a "normal" type signature.  Moreover, it is not
possible for a guard to end with a non-expression type signature, so
the report clearly means "avoid guards that end with an expression
type signature"--the word expression has been dropped because it is
clear from context.

Unfortunately, the context of section 4.5.1 provides less help.  There
is no a priori reason why b should depend on a in a pair of bindings
such as these:

	a = const (\x -> x) b
	b = const (a :: Int -> Int) (a :: Bool -> Bool)

Thanks to your email on haskell cafe, I now understand that the spec
considers these two bindings as one declaration group, which explains
why GHC rejects the program.  I assume this is to facilitate type
checking at the time of type inference (which, if so, might be worth
pointing out to help the reader's intuition).

By contrast, the Haskell98 report is dead clear that both bindings
above form a single declaration group and hence that the program
should be rejected.  But someone familiar with Haskell98 might read
section 4.5.1 of the 2010 report and say "oh, they seem to want to
shrink declaration groups by breaking dependencies when a
programmer-specified type can short-cut type inference."  That leads
to interpreting "a free identifier that has no type signature" as a
more concise formulation of "a free identifier that has neither an
expression type signature nor a normal type signature in the
declaration list."

Even if you don't think the report is ambiguous, it is at least prone
to misinterpretation, which is why a couple of examples would really
help at the end of 4.5.1.

> We could simplify that even further:
>   We say that a given declaration group is unrestricted if it comprises either
>   (a): one or more function bindings, or
>   (b): a simple pattern binding for a variable that has a type signature.
>        Note that it follows from the definition in Section 4.5.1 that
>        such a binding always constitutes a declaration group by itself.

Yes, I much prefer your formulation to mine.  Succinct and very clear.


More information about the Haskell-prime mailing list