我有一个类型
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
答案 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 -> ...