在Haskell中强制转换为多参数类型

时间:2011-09-02 20:31:28

标签: haskell polymorphism coercion

我有一个类型

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

2 个答案:

答案 0 :(得分:2)

newtype不仅仅是一个同义词,而是一种创建类型级别不同的类型的方法(虽然稍后相同)。那就是说 - 你需要使用你的数据构造函数显式地包装它。此外,上下文无效。你仍然需要在任何地方输入它。

答案 1 :(得分: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]

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

func :: (Num a, IntegerAsType n) => PolyRing a n -> ...