On Thu, 6 Jan 1994, Simon L Peyton Jones wrote:

> OK, here's my example.  I hope it's right.  I was writing a compiler
> pass which looked at a data type something like
> 
>       data Expr = Let Bind Expr
>                 | ...
> 
>       data Bind = MkBind String Expr
> 
> Then I had three functions, written in continuation-passing styule, as
> follows:
> 
>       doBinds :: [Bind] -> [Bind]
>       doBinds (b:bs) = doBindAndScope b (\b' -> b' : doBinds bs)
> 
>       doExpr :: Expr -> Expr
>       doExpr (Let b e) = doBindAndScope b (\b' -> Let b' (doExpr e))
> 
>       doBindAndScope :: Bind -> (Bind -> a) -> a
>       doBindAndScope (MkBind s e) cont = cont (MkBind s (doExpr e))
> 
> The trouble is that the mutual recursion between 
> 
>       doBindsAndScope         doExpr
> 
> means that doBindsAndScope can't be as polymorphic as its type
> signature says it should be.  But if it isn't that polymorphic, the
> call in doBinds is illegal.  
> 
> I solved it like this (UTTERLY YUK YUK), by encapsulating the polymorphism
> in a fixed data type which simply tags the various expected types at
> which the function can be called.  Not only is this really quite obscure, 
> but it also is inefficient at runtime.

Hmm...very irritating. An alternative to Simon's solution would be:

        doBinds (b:bs) = doBindAndScope b doExpr (\b' -> b' : doBinds bs)

        doExpr (Let b e) = doBindAndScope b doExpr (\b' -> Let b' (doExpr e))

        doBindAndScope :: Bind -> (Expr -> Expr) -> (Bind -> a) -> a
        doBindAndScope (MkBind s e) f cont = cont (MkBind s (f e))

This works by removing the mutual recursion at the expense of
introducing an unwanted additional parameter. Maybe not UTTERLY
horrible but still not very nice.

OK - I'm convinced that allowing polymorphic recursion in the presence
of type signatures is useful, so perhaps it would be worth complicating
the type system a bit to allow it. After all, what's a bit of extra
complexity when there's so much in there already :-).

Sebastian


Reply via email to