
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 = let g :: a -> a | a, Eq a g = ... in 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: let 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. http://www.metamilk.com