Haskell类型类中的不明确类型

Haskell类型类中的不明确类型,haskell,typeclass,Haskell,Typeclass,我想使用参数化类型类。下面是我的源代码: 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

我想使用参数化类型类。下面是我的源代码:

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类型释放类的实例?

假设有一个对您的
build3D
的调用。从该调用的上下文中,编译器必须找到适当的实例。这包括查找变量的值
cakv
。但是,
build3D
的类型没有提到
kv
,因此不可能找到它们

更具体地说,如果我们有

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,…
是所有变量
cak 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

现在,每个调用应该类似于
build3D(Proxy::Proxy K1)(Proxy::Proxy V1)x1 x2 x3

假设有一个对
build3D
的调用。从该调用的上下文中,编译器必须找到适当的实例。这包括查找变量的值
cakv
。但是,
build3D
的类型没有提到
kv
,因此不可能找到它们

更具体地说,如果我们有

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,…
是所有变量
cak 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
现在,每个调用应该类似于
build3D(Proxy::Proxy K1)(Proxy::Proxy V1)x1 x2 x3