害怕我在Haskell中严重误解了类型。我会进入它。假设我有一个定义的类型:
type Vector = [Num a]
所以我在同义词的定义中使用类型类。然后,如果我想将它添加到另一个类型类,比如Eq,也许我会这样做:
instance Eq Vector a where
[] == [] = True
[_]== [] = False
[] == [_] = False
(a : u) == (b : v) = (a == b) && (u == v)
但是当我这样做时,GHC会给出一个
解析输入' ['
它引用了行[_]== [] = False
中的第一个左括号。
这是由我的类型定义问题引起的吗?
答案 0 :(得分:1)
此代码存在多个问题,导致无法编译。我认为您的意思是Vector
由其包含的类型a
参数化:
type Vector a = [a]
我放弃了Num
约束,因为其他示例并不需要它;我会在最后拿起它。
已经列出了Eq
个实例,所以这有点死路一条。前进的方法是切换到新类型:
newtype Vector a = Vector [a]
与使用type
声明的类型同义词不同,Haskell将newtype
视为完全不同的类型。 Vector
不是列表,因此我们可以定义我们想要的任何类型类实例。
我们的Eq
实例会更长一些,因为我们每次都必须编写Vector
构造函数。我在第一行的Vector a
附近添加了括号。
我们需要做的唯一其他更改是在实例之前添加Eq a
约束。在定义的最后一行,我们比较了两个Vectors
的第一个元素。仅当类型a
是Eq
的实例时才有意义。
instance Eq a => Eq (Vector a) where
Vector [] == Vector [] = True
Vector [_] == Vector [] = False
Vector [] == Vector [_] = False
Vector (a : u) == Vector (b : v) = (a == b) && (Vector u == Vector v)
这个编译。您可以添加Num
约束,坚持认为除非Vector a
为a
,或Num
仅为Vector a
,否则任何人都无法构建Eq
如果a
是Num
。如果这是你想要做的事情,我可以添加一个例子。