我想使用参数化类型类。以下是我的源代码:
class (CContext3D c k v) => CBuilder3D c a k v where
build3D :: c -> a -> String -> HSL HLangJS HLangJS
编译时收到以下错误:
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
以下代码正常运行:
class (CContext3D c KeyContext3D String) => CBuilder3D c a where
build3D :: c -> a -> String -> HSL HLangJS HLangJS
如何根据k和v类型发布类的实例?
答案 0 :(得分:3)
假设您有// Download a file:
fileTransfer.download(..).then(..).catch(..);
的电话。从该调用的上下文中,编译器必须找到适当的实例。这涉及查找变量build3D
的值。但是,c a k v
的类型没有提及build3D
,因此无法找到它们。
更具体地说,如果我们有
k v
它们的相关instance CBuilder3D c a K1 V1 where ...
instance CBuilder3D c a K2 V2 where ...
函数具有完全相同的类型,编译器无法选择其中一种。
可能的解决方案:
如果可能,您应该使用函数依赖项或类型系列来声明build3D
和k
的值由其他参数确定。这可能是这种情况,具体取决于您的具体类别。
否则,您可以尝试启用v
和AllowAmbiguousTypes
,并保持模糊类型。但是,在每次调用时,您现在必须明确指定这些类型,如TypeApplications
中build3D @t1 @t2 @t3 @t4 x1 x2 x3
是所有变量t1,...
的类型。不太方便。
另一个选项是让c a k v
出现在带代理的类型中:
k,v
现在每个电话都应该是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
。