最小示例代码:
class IntegralAsType a where
value :: (Integral b) => a -> b
class (Num a, Fractional a, IntegralAsType q) => Zq q a | a -> q where
changeBase:: forall p b . (Zq q a, Zq p b) => a -> b
newtype (IntegralAsType q, Integral a) => ZqBasic q a = ZqBasic a deriving (Eq)
zqBasic :: forall q a . (IntegralAsType q, Integral a) => a -> ZqBasic q a
zqBasic x = ZqBasic (mod x (value (undefined::q)))
instance (IntegralAsType q, Integral a) => Zq q (ZqBasic q a) where
changeBase (ZqBasic x) = fromIntegral (value (undefined::p)) -- ZqBasic is an instance of Num
这是我要完成的工作的一些背景知识: IntegralAsType 通过防止将两个具有不同模数的数字相加来确保编译时的类型安全。ZqBasic 是 Zq 类型的内部表示,还有其他类型,这就是 Zq 被这样定义的原因。目标是获得一个对内部表示透明的系统。
我的问题是 changeBase 函数。我在'p'类型上使用了显式forall,但我仍然得到一个“由于使用值而产生的约束中的模糊类型变量a0(IntegralAsType a0)”
我对为什么会收到此错误感到困惑。特别是在上一篇文章中,我得到了类似“zqBasic”函数的帮助,它似乎与 changeBase 函数具有相同的设置。我通过添加显式量词“forall qa”修复了 zqBasic 中的模棱两可的变量错误。如果没有这个量词,我会得到一个模棱两可的类型变量错误。我明白为什么我需要量词,但我不明白为什么它似乎对 changeBase 没有帮助。
谢谢