类型同义词的类型类实例

时间:2015-08-21 17:32:55

标签: haskell types

害怕我在Haskell中严重误解了类型。我会进入它。假设我有一个定义的类型:

type Vector = [Num a]

所以我在同义词的定义中使用类型类。然后,如果我想将它添加到另一个类型类,比如Eq,也许我会这样做:

instance Eq Vector a where
  [] == [] = True
  [_]== [] = False
  [] == [_] = False
  (a : u) == (b : v) = (a == b) && (u == v)

但是当我这样做时,GHC会给出一个

  

解析输入' ['

它引用了行[_]== [] = False中的第一个左括号。

这是由我的类型定义问题引起的吗?

1 个答案:

答案 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的第一个元素。仅当类型aEq的实例时才有意义。

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 aa,或Num仅为Vector a,否则任何人都无法构建Eq如果aNum。如果这是你想要做的事情,我可以添加一个例子。