最小限のサンプルコード:
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は、モジュラスが異なる2つの数値の加算などを防ぐことにより、コンパイル時の型の安全性を保証します。ZqBasicはZqタイプの内部表現であり、他にもあります。そのため、Zqはそのように定義されています。目標は、内部表現に対して透過的なシステムを取得することです。
私の問題はchangeBase関数にあります。'p'型で明示的なforallを使用していますが、それでも「値の使用から生じる制約(IntegralAsType a0)のあいまいな型変数a0」を取得します。
なぜこのエラーが発生するのか混乱しています。特に前回の投稿では、changeBase関数と同じ設定になっているように見える「zqBasic」関数のようなものについて助けを得ました。明示的な数量詞'forallqa'を追加することにより、zqBasicのあいまいな変数エラーを修正しました。この数量詞がないと、あいまいな型変数エラーが発生します。なぜそこに数量詞が必要なのかは理解できますが、それがchangeBaseに役立たないように見える理由はわかりません。
ありがとう