Haskell - Could not deduce ... from Context error - OpenGL AsUniform class type

62 views Asked by At

I'm working on making my data types general instead of taking in the OpenGL type GLfloat. So I started making it take in type a and then just replacing everything with that.

Now, I've come to a point where I'm setting uniform variables, but they take in GLfloat's. I'm using a library called GLUtil which makes it a bit easier, which has provided a class AsUniform, to check whether the type can be a uniform variable or not. I stick it in my type signature, but it stills gives me an error. Here's the code:

-- | Sets the modelview and projection matrix uniform variables.
mvpUnif :: (GL.UniformComponent a, Num a, Epsilon a, Floating a, AsUniform a) => (GLState a) -> ShaderProgram  -> IO ()
mvpUnif state p = do
-- Check if view and projection matrices are there, else set them to the identity.
let vMat = case vMatrix state of
    Just v -> v
    Nothing -> getIdentity
let pMat = case pMatrix state of
    Just p -> p
    Nothing -> getIdentity
-- Multiply model and view matrix together.
let mvMatrix = vMat !*! mMatrix state
setUniform p uModelViewMatrixVar mvMatrix
setUniform p uProjectionMatrixVar pMat

and the error:

Could not deduce (AsUniform (V4 (V4 a)))
  arising from a use of `setUniform'
from the context (GL.UniformComponent a,
                  Num a,
                  Epsilon a,
                  Floating a,
                  AsUniform a)
  bound by the type signature for
             mvpUnif :: (GL.UniformComponent a, Num a, Epsilon a, Floating a
,
                         AsUniform a) =>
                        GLState a -> ShaderProgram -> IO ()
  at src\Graphics\FreeD\Shaders\DefaultShaders.hs:194:12-119
In a stmt of a 'do' block:
  setUniform p uModelViewMatrixVar mvMatrix
In the expression:
  do { let vMat = ...;
       let pMat = ...;
       let mvMatrix = vMat !*! mMatrix state;
       setUniform p uModelViewMatrixVar mvMatrix;
       .... }
In an equation for `mvpUnif':
    mvpUnif state p
      = do { let vMat = ...;
             let pMat = ...;
             let mvMatrix = ...;
             .... }

V4 is made an instance of AsUniform, as well as M44, which is a type for (V4 (V4 a)), which I thought might be the issue, so I'm not sure why it's acting up.

Here's the source for the class:

http://hackage.haskell.org/package/GLUtil-0.8.5/docs/Graphics-GLUtil-Linear.html

Thanks!

1

There are 1 answers

1
Athan Clark On BEST ANSWER

Try adding -XFlexibleContexts and the constraint, literally, to your existing answer:

{-# LANGUAGE FlexibleContexts #-}

mvpUnif :: ( GL.UniformComponent a
           , Num a
           , Epsilon a
           , Floating a
           , AsUniform a
           , AsUniform (V4 (V4 a))
           ) => (GLState a) -> ShaderProgram  -> IO ()

Usually this is the routine for constraints that aren't inferrable, or where constraints need to be transitively included in all call sites. This happens to me all the time with MonadState et al. In this case, setUniform is the culprit.