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]]