Quantcast
Channel: Haskell - Ambiguous type variable - Stack Overflow
Viewing all articles
Browse latest Browse all 3

Haskell - Ambiguous type variable

$
0
0

I am having trouble with ambiguous types in Haskell. I started out with the following:

module GameState( GameState(..), GameStateMonad, module Control.Monad.Trans, module Control.Monad.Trans.State.Lazy, Blank(..)) whereimport Control.Monad.Transimport Control.Monad.Trans.State.Lazytype GameStateMonad a b = StateT a IO bclass GameState a where    update :: Double -> GameStateMonad a ()    update deltaTime = return ()    draw :: GameStateMonad a ()    draw = return ()    getNextState :: GameState b => GameStateMonad a (Maybe b)    getNextState = return Nothing    isStateFinished :: GameStateMonad a Bool    isStateFinished = return True-- This is just a dummy data and instance declaration to demonstrate the errordata Blank = Blankinstance GameState Blank

Then when I try to run the following in ghci:

runStateT getNextState Blank

I get:

Ambiguous type variable `b0' in the constraint:  (GameState b0) arising from a use of `getNextState'Probable fix: add a type signature that fixes these type variable(s)...

I thought it was complaining that my default implementation of the getNextState function didn't specify a concrete type, so I tried the following:

getNextState :: GameState b => GameStateMonad a (Maybe b)getNextState = return (Nothing :: Maybe Blank)

Unfortunately I got this error while compiling:

Could not deduce (b ~ Blank)from the context (GameState a)  bound by the class declaration for `GameState'  at GameState.hs:(14,1)-(25,33)or from (GameState b)  bound by the type signature for             getNextState :: GameState b => GameStateMonad a (Maybe b)  at GameState.hs:22:5-50  `b' is a rigid type variable bound by      the type signature for        getNextState :: GameState b => GameStateMonad a (Maybe b)      at GameState.hs:22:5...

But I found that adding a type signature when I call getNext state allows the code to run:

runStateT (getNextState :: GameStateMonad Blank (Maybe Blank)) Blank

Unfortunately this stops me from making generic code to handle game states. It also makes little sense to me. What's the point in returning a polymorphic type if you have to give it an explicit type after it's returned? The original issue is also really confusing to me because I can make a function as follows:

test :: Num a => Maybe atest = Nothing

And have no problems running it. Shouldn't this complain about ambiguous types like my original code? Also when giving the return value an explicit type I cannot compile it, like before:

test :: Num a => Maybe atest = Nothing :: Maybe Int

I don't see why this is a problem. Int is an instance of type Num so the type of the function is correct.

I have four questions:

  1. Why does giving an explicit type when returning an element of a typeclass cause a compile error?

  2. Why does returning an ambiguous Maybe value inside of getNextState cause an error but inside test it does not?

  3. Why does this error occur without me calling a function on the returned polymorphic data, as explained here?

  4. In the link above, the answer mentions that "[you get this error] because you have something that produces a polymorphic result, then apply a function that takes a polymorphic argument to that result, such that the intermediate value's type is unknown". Doesn't this mean that functions that return a polymorphic result are essentially useless?

Thanks.


Viewing all articles
Browse latest Browse all 3

Latest Images

Trending Articles





Latest Images