类型同义词的类型类实例
Posted
技术标签:
【中文标题】类型同义词的类型类实例【英文标题】:Typeclass instance for type synonym 【发布时间】:2015-11-15 17:53:58 【问题描述】:恐怕我严重误解了 Haskell 中的类型。我会进入它。假设我定义了一个类型:
type Vector = [Num a]
所以我在同义词的定义中使用了一个类型类。然后,如果我想将它添加到另一个类型类,比如 Eq,也许我会这样做:
instance Eq Vector a where
[] == [] = True
[_]== [] = False
[] == [_] = False
(a : u) == (b : v) = (a == b) && (u == v)
但是当我这样做时,GHC 给出了一个
输入'['解析错误
它指的是[_]== [] = False
行中的第一个左括号。
这是由我的类型定义问题引起的吗?
【问题讨论】:
您复制到问题中的内容是否有错字或遗漏?我不相信你有type Vector = [Num a]
,因为类型变量a
不存在。如果你这样做了,Num
类型是什么?它不能是基类中的 Num
类,因为这是一个约束,而不是一个类型。
如果Vector a
是一个定义为列表[F a]
的类型同义词,你为什么要为它编写一个Eq
实例? Eq a => Eq [a]
已经有一个 Eq
实例。
@AndreyChernyakhovskiy 我的 7.10 GHCi 对象 type Vector a = [Num a]
出现错误 Expected kind '*', but 'Num a' has kind 'Constraint'
,即使启用了 PolyKinds
和 DataKinds
也不足为奇。
@Cirdec,我的是 7.6.3。看起来已经修复了一个错误。
顺便说一句,如果我没记错的话,不能在类型同义词上定义类型类的实例。
【参考方案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
约束,坚持除非a
是Num
,否则没有人可以构造Vector a
,或者如果a
是Num
,则Vector a
只是Eq
。如果这是您想做的事情,我可以添加一个示例。
【讨论】:
不要添加错误代码的示例。此类限制几年前就已经取消了。 @dfeuer,这是对我给出的例子的批评,还是只是对我最后一段的回应?如果是后者 - 是的,我把它省略了,因为这是一种不好的做法。 @bergey 很抱歉提出一个旧帖子,但我对学习 Haskell 很感兴趣。为了确保Vector
只能包含作为Num
实例的类型,量化类型可以吗? data Vector a = forall a . Num a => Vector [a]
?还是有更“直接”的方式来做到这一点?
@StevenL。我认为你会更好地为你的帖子提出一个新问题。如果你解释你正在尝试做的更广泛的背景,你会得到更好的答案。你想允许和禁止什么?你提议的类型没有做你想做的事,但不知道你想要什么什么我不知道还有什么建议。以上是关于类型同义词的类型类实例的主要内容,如果未能解决你的问题,请参考以下文章
Python/Django:数据库模型中字段“类型”的同义词(保留的内置符号)
oracle中啥是同义词,它有几种类型,不同类型同义词的区别是啥?并写出语法?