У меня есть довольно простая функция, которая принимает параметризованный тип данных и возвращает тот же тип:
{-# LANGUAGE ScopedTypeVariables #-}
class IntegerAsType a where
value :: a -> Integer
newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a] deriving (Eq)
normalize :: (Num a, IntegerAsType n) => (PolyRing a n) -> (PolyRing a n)
normalize r@(PolyRing xs) | (genericLength xs) == len = r
| ... [other cases]
where len = (value (undefined :: n))
Идея состоит в том, что normalize возьмет PolyRing со списком любого размера, а затем вернет новый PolyRing с дополненным/модифицированным вектором коэффициентов длины n, где n является частью типа переданного PolyRing.
Я получаю сообщение об ошибке:
Ambiguous type variable `a0' in the constraint:
(IntegerAsType a0) arising from a use of `value'
Я просмотрел все другие сообщения SO об этой ошибке и до сих пор ничего не нашел. Ошибка возникает, даже если я удалю все ссылки на 'len' (но оставлю их в предложении where), поэтому проблема связана с
(value (undefined :: n))
что практически идентично тому, как я использовал IntegerAsType в других местах.
Пока вы этим занимаетесь, я также принимаю предложения об альтернативах системе параметризованных типов, которую я сейчас использую. В частности, это проблема, потому что мне приходится определять IntegerAsType для множества разных значений. Мы используем типы, а не параметры, чтобы гарантировать, например, что вы не можете добавить два элемента из разных колец полиномов (параметр 'a' гарантирует, что вы не сможете добавить кольца полиномов из одного и того же полинома, но над разными базовыми кольцами). ).
Спасибо
PolyRing
нигде не хранит значение типаn
, единственное, что ваш клиентский код может сделать сn
, — это вызватьvalue
для неопределенного значения этого типа. Так почему у вас есть этот тип вокруг? Почему бы просто не использовать вместо этогоdata PolyRing a = PolyRing Integer [a]
, как если бы вы уже вызвалиvalue
для пользователя? - person Daniel Wagner   schedule 03.09.2011newtype
. Это не имеет смысла и устарело. - person augustss   schedule 04.09.2011