Haskell类型类中的不明确类型

时间:2017-04-07 07:50:43

标签: 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 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类型发布类的实例?

1 个答案:

答案 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 ... 函数具有完全相同的类型,编译器无法选择其中一种。

可能的解决方案:

如果可能,您应该使用函数依赖项或类型系列来声明build3Dk的值由其他参数确定。这可能是这种情况,具体取决于您的具体类别。

否则,您可以尝试启用vAllowAmbiguousTypes,并保持模糊类型。但是,在每次调用时,您现在必须明确指定这些类型,如TypeApplicationsbuild3D @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