Минимальный пример кода:
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. Я использую явный forall для типа 'p', но все еще получаю "неоднозначную переменную типа a0 в ограничении (IntegralAsType a0), возникающую из-за использования значения"
Я смущен тем, почему я получаю эту ошибку. В частности, в предыдущем посте я получил помощь с чем-то вроде функции «zqBasic», которая, по-видимому, имеет те же настройки, что и функция changeBase. Я исправил ошибку неоднозначной переменной в zqBasic, добавив явный квантификатор 'forall q a .' Без этого квантификатора я получаю ошибку переменной неоднозначного типа. Я понимаю, зачем мне там нужен квантификатор, но я не понимаю, почему он не помогает для changeBase.
Спасибо