问题
I have a pretty straightforward function that takes a parameterized data type and returns the same type:
{-# 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))
The idea is that normalize will take a PolyRing with a list of any size and then return a new PolyRing with a padded/modded coefficient vector of length n, where n is part of the type of the PolyRing passed in.
I'm getting the error:
Ambiguous type variable `a0' in the constraint:
(IntegerAsType a0) arising from a use of `value'
I've looked at all of the other SO posts on this error, and still have nothing. The error occurs even if I remove all references to 'len' (but keep it in the where clause), so the problem is with
(value (undefined :: n))
which is virtually identical to how I've used IntegerAsType in other places.
While you are at it, I'm also taking suggestions for alternatives to the parameterized type system I'm using now. In particular, it is a pain because I have to define IntegerAsType for lots of different values. We are using the types rather than parameters to ensure, for example, that you can't add two elements of different polynomial rings (the parameter 'a' makes sure you can't add polynomial rings mod the same polynomial but over different underlying rings).
Thanks
回答1:
The signature for normalize
doesn't create the scope for the type variable n
in undefined :: n
.
Try this:
normalize r@(PolyRing xs :: PolyRing a n) | ... = ...
where len = value (undefined :: n)
Alternatively, you can use an explicit forall
in the type signature for normalize
:
normalize :: forall a n . (Num a, IntegerAsType n) => (PolyRing a n) -> (PolyRing a n)
normalize r@(PolyRing xs) | ... = ...
where len = value (undefined :: n)
See http://www.haskell.org/ghc/docs/7.0.3/html/users_guide/other-type-extensions.html#decl-type-sigs
来源:https://stackoverflow.com/questions/7294149/ambiguous-type-using-parameterized-types-haskell