Reputation: 577
I want to use parametrized type class. Below is my source code:
class (CContext3D c k v) => CBuilder3D c a k v where
build3D :: c -> a -> String -> HSL HLangJS HLangJS
At compilation I receive the following error:
Could not deduce (CBuilder3D c a k0 v0)
from the context: CBuilder3D c a k v
bound by the type signature for:
build3D :: CBuilder3D c a k v =>
c -> a -> String -> HSL HLangJS HLangJS
The following code works correctly:
class (CContext3D c KeyContext3D String) => CBuilder3D c a where
build3D :: c -> a -> String -> HSL HLangJS HLangJS
How is it possibly to release instance of class depending from k and v types?
Upvotes: 0
Views: 280
Reputation: 116174
Suppose there is a call to your build3D
. From the context of that call, the compiler has to find a proper instance. This involves finding values for variables c a k v
. However, the type of build3D
do not mention k v
, so it would be impossible to find those.
More concretely, if we had
instance CBuilder3D c a K1 V1 where ...
instance CBuilder3D c a K2 V2 where ...
their related build3D
function would have exactly the same type, and the compiler has no way to choose one of those.
Possible solutions:
If possible, you should use functional dependencies or type families to state that the value of k
and v
are determined by the other parameters. This might be the case or not, depending on your specific class.
Otherwise, you could try enabling AllowAmbiguousTypes
and TypeApplications
, and keep the ambiguous type around. However, at every call, you now will have to specify those types explicitly as in build3D @t1 @t2 @t3 @t4 x1 x2 x3
where t1,...
are the types for all the variables c a k v
. Not terribly convenient.
Another option is to make k,v
to appear in the type with a proxy:
import Data.Proxy
class (CContext3D c k v) => CBuilder3D c a k v where
build3D :: proxy k -> proxy v -> c -> a -> String -> HSL HLangJS HLangJS
now each call should be something like build3D (Proxy :: Proxy K1) (Proxy :: Proxy V1) x1 x2 x3
.
Upvotes: 3