Ambiguous type using parameterized types Haskell

别等时光非礼了梦想. 提交于 2020-01-07 02:04:23

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!