Consider the following recursive function binding:

> f []          = 0::Int
> f (x:xs)      = 1 + f([]::[Int]) + f([]::[Bool]) + f xs

This binding is ill-typed since f is used in two different instances
of its polymorphic-to-be type.  Indeed, the above declaration is
rejected by hbc, ghc, and gofer.

However, the restriction can be overcome by declaring a class
containing the function.  The following program compiles and runs
without complaints under all three:

> class F a where
>   f :: a -> Int
> 
> instance F [a] where
>   f []        = 0::Int
>   f (x:xs)    = 1 + f([]::[Int]) + f([]::[Bool]) + f xs

This is fine from a type inference point of view since f is declared
and given a polymorphic type at the point where the class is defined.

There are some useful applications for this, particularly in
connection with existential types.  Any thoughts or comments?  Is this
a well-known technique?

-Konstantin [[EMAIL PROTECTED]]

Reply via email to