
The following code has ambiguity, but I can't figure out how to get around it. Am I missing something trivial? Am I going in the wrong direction? Thank you in advance for your time and for any help that you can offer.
data MehQueue = MehQueue
class MehBase a where new :: IO a instance MehBase MehQueue where new = return MehQueue
class (MehBase a) => HasShift a where shift :: a -> IO a instance HasShift MehQueue where shift a = return a
main :: IO () main = do x <- new shift x return ()
Please note that I intend to extend this example with MehStack, HasPush and HasPop. You can probably guess where I'm going with all this.

On 4/16/07, Paul Wankadia
The following code has ambiguity, but I can't figure out how to get around it. Am I missing something trivial? Am I going in the wrong direction? Thank you in advance for your time and for any help that you can offer.
How about changing
x <- new
to
x <- new :: IO MehQueue
? I'm not a professional haskeller, probably there's a better alternative =). Cheers, -- Felipe.

On 16/04/07, Paul Wankadia
Is it impossible for the compiler to infer the type from the methods called?
Your code:
main :: IO () main = do x <- new
From the use of 'new', the compiler can infer that the type of x is an instance of MehBase, and...
shift x
from the use of 'shift', that it is an instance of HasShift.
return ()
So we have x :: (MehBase a, HasShift a) => a. There isn't enough
information provided to pin down 'a' any more precisely, so GHC can't
figure out which 'new' or 'shift' you mean (remember that type classes
provide overloading), and gives up.
There is one special case where the compiler does infer a specific
type despite not having enough information to do so, and that is where
the class(es) is/are numeric. For example (Floating a) => a might
default to Float or Double. This is one case where the compiler
decides it can make 'reasonable' assumptions as to what you actually
wanted. It's also why ambiguous types seem to work in the interpreter,
if you've only ever looked at numeric ones. In the case of the code
you posted, GHC isn't smart enough to realise that there's only one
type in scope that satisfies the constraints.
Here's the relevant part of the report:
http://www.haskell.org/onlinereport/decls.html#sect4.3.4
Felipe's suggestion is probably the best way to fix it, i.e. tell the
compiler exactly which type you want. The report seems to suggest you
can give the compiler a list of defaults in the module declaration but
I don't know if that would be sensible.
--
Peter Berry
participants (3)
-
Felipe Almeida Lessa
-
Paul Wankadia
-
Peter Berry