3

我有一个类型

class IntegerAsType a where
  value :: a -> Integer

data T5
instance IntegerAsType T5 where value _ = 5

newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a]

我的主要问题是:如何在特定变量中定义变量PolyRing

它应该是这样的:

x = [1, 2, 3] :: Integer T5

(我认为)问题是: 之后的正确语法是::什么?

我收到错误

Couldn't match expected type `PolyRing Integer T5'
         with actual type `[t0]'
In the expression: [1, 2, 3] :: PolyRing Integer T5
In an equation for `x': x = [1, 2, 3] :: PolyRing Integer T5

另外,我正在寻找一种更好的方法来实现这一点。特别是,我真的希望a从列表元素的类型中推断出类型,而IntegerAsType n必须指定(它不应该取决于列表的长度,即使这是可能的)。

到目前为止我尝试过的事情:

x = [1,2,3] :: PolyRing (Integer, T5)

x = [1,2,3] :: PolyRing Integer T5
4

2 回答 2

2

Anewtype不仅是同义词,而且是一种在类型级别创建不同类型的方法(尽管稍后相同)。也就是说 - 您需要使用数据构造函数显式包装它。此外,上下文没有影响。您仍然必须在任何地方输入它。

于 2011-09-02T20:39:31.937 回答
2

第一注

数据类型上下文,例如:

newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a]

通常是一个坏主意,并且已从该语言中退休。

忽略那个

要构造实例,您必须使用数据构造函数PolyRing

PolyRing [1,2,3]

但这还不够,到目前为止的类型推断将是(IntegerAsType n) => PolyRing Integer n. 您的最终类型签名将完成此操作let x = PolyRing [1,2,3] :: PolyRing Integer T5

回到第一个音符

不过,也许你想要:

newtype PolyRing a n = PolyRing [a]

每个构建或使用 polyring 的函数都可以强制执行所需的约束:

func :: (Num a, IntegerAsType n) => PolyRing a n -> ...
于 2011-09-02T20:40:38.200 回答