使用参数化类型的不明确类型 Haskell

发布于 2024-12-02 23:01:33 字数 1063 浏览 7 评论 0原文

我有一个非常简单的函数,它接受参数化数据类型并返回相同的类型:

{-# 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))

这个想法是,归一化将采用具有任意大小的列表的 PolyRing,然后返回一个具有长度为 n 的填充/修改系数向量的新 PolyRing,其中 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”确保您不能添加多项式环 mod 相同的多项式但在不同的基础环上)。

谢谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

百合的盛世恋 2024-12-09 23:01:33

normalize 的签名不会在 undefined :: n 中创建类型变量 n 的作用域。

试试这个:

normalize r@(PolyRing xs :: PolyRing a n) | ... = ...
          where len = value (undefined :: n)

或者,您可以在 normalize 的类型签名中使用显式 forall

normalize :: forall a n . (Num a, IntegerAsType n) => (PolyRing a n) -> (PolyRing a n)
normalize r@(PolyRing xs) | ... = ...
      where len = value (undefined :: n)

请参阅 http://www.haskell.org/ghc/docs/7.0.3/html/users_guide/other-type-extensions.html#decl-type-sigs

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文