[Haskell-cafe] A better syntax for qualified operators?

Brian Hulley brianh at metamilk.com
Thu Sep 28 02:26:13 EDT 2006

Bas van Dijk wrote:
> On Wednesday 27 September 2006 22:20, Brian Hulley wrote:
>> (The other change needed for LL(1) is to give contexts a marker
>> before they appear eg:
>> foo :: {MonadIO m} a -> m a
>> )
> Or move contexts to the end of a type and separate it with a | like
> Clean does: (See 6.2 of
> http://clean.cs.ru.nl/download/Clean20/doc/CleanRep2.0.pdf)
> foo :: a -> m a | MonadIO m
> Personally I like this style because I always think first about what
> the type of the function should be (a -> m a) and then about the
> contexts / restrictions that hold for the variables (MonadIO).
> I do the same thinking when writing list comprehensions. First I
> think of the general form of the elements in the list: [ (a, b) ...
> then I think about the restrictions on the variables: | a <- [1..10],
> b <- [1..10], a > b]

I also like this style (introduced to the Haskell world by Bulat in 
http://www.haskell.org/pipermail/haskell/2006-September/018466.html) for the 
same reasons, and also because visually I think it looks really great. The 
problem with it as far as an editor is concerned is that the type variables 
are used before they are quantified, so any feedback about lexical scoping 
may be wrong till the context has been entered eg:

    class C q where foo :: q -> q

    instance C (T a b) | Eq a, Eq b where

        foo x =
                g :: a -> a | a, Eq a
                g = ...
                g x

Here the local nature of the type variable 'a' in 'g' is not known while 
a->a is being entered ie the user knows that the 'a' is going to be a local 
type variable but the editor will tell the user it is the 'a' of the 
instance decl thus resulting in a poor editing experience.
An alternative would be to write:

                g :: forall a. a-> a | Eq a

but this isn't so nice because then the quantifier is separated from the 
restrictions in the context, which I think should really be regarded as part 
of the quantifier itself.

A possible solution would be to just forbid shadowing of type variables 
altogether, which is maybe not as draconian as it sounds, especially when 
there is so much to gain from using the neat | syntax and a good precedent 
for it's use.

As an aside, regarding lexical scoping of type variables, it might in future 
be very useful to have the rule that variables not explicitly quantified are 
scoped over the entire enclosing *top level* declaration (or the highest 
level decl that makes sense) hence the need for a very parsimonious syntax 
such as f :: a -> b | a, b instead of the long-winded and sometimes 
confusing "forall" keyword.

Regards, Brian.
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.


More information about the Haskell-Cafe mailing list