scoped type vars, how to manage without?

Richard A. O'Keefe ok@atlas.otago.ac.nz
Fri, 19 Mar 1999 16:42:57 +1300 (NZDT)


Here's a function that shows a pattern I would like to use from time
to time.

    :: Tree t = Leaf t | Fork (Tree t) (Tree t)

    :: Choice = Left | Right

    :: Path :== [Choice]

    paths :: (a -> Bool) (Tree a) -> *[*Path]                  //1
    paths p t = loop t []
      where loop :: (Tree a) *[*Path] -> *[*Path]              //2
            loop (Leaf x) h | p x  = [[]:h]  // one empty path
                            | True = h    // no paths
            loop (Fork l r) h = prefix Left (loop l [])
                                 (prefix Right (loop r []) h)
            prefix :: Choice *[*Path] *[*Path] -> *[*Path]
            prefix _ [] h = h
            prefix c [x:xs] h = [[c:x]:prefix c xs h]


If I try to compile that, I'm told
specified type is too polymorphic (contains monomorphic type variables)
and the message directs me to the line labelled //2.

The reason is obvious:  the type variable 'a' in that line is a DIFFERENT
type variable from the type variable 'a' in line //1.  In Haskell, they've
fixed that by letting type variables have a wider scope; without scoped
type variables there is *NO* way I can specify the type of //2 loop.

There are several functions that I've recently had to rewrite because
the compiler wasn't inferring that 'loop :: ... *x -> *x' and I 
couldn't give it a helping hand because the type was inexpressible.
Oddly enough, the trick in each case has involved adding a function
like 'prefix' which I _could_ type.

What do other people do?
Are there any plans to add scoped type variables to Clean?