【问题标题】:Ambiguous type in Haskell type classHaskell 类型类中的歧义类型
【发布时间】:2017-04-07 07:50:42
【问题描述】:

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

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

【问题讨论】:

    标签: haskell typeclass


    【解决方案1】:

    假设有人打电话给您的build3D。从该调用的上下文中,编译器必须找到一个合适的实例。这涉及查找变量c a k v 的值。但是build3D的类型并没有提到k v,所以根本找不到。

    更具体地说,如果我们有

    instance CBuilder3D c a K1 V1 where ...
    instance CBuilder3D c a K2 V2 where ...
    

    它们相关的build3D 函数将具有完全相同的类型,编译器无法选择其中之一。

    可能的解决方案:

    如果可能,您应该使用函数依赖项或类型族来声明kv 的值由其他参数确定。这可能是这种情况,也可能不是,取决于你的具体班级。

    否则,您可以尝试启用AllowAmbiguousTypesTypeApplications,并保留不明确的类型。但是,在每次调用时,您现在都必须像在 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
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 2013-11-05
      • 2013-06-28
      • 1970-01-01
      相关资源
      最近更新 更多