为什么不能将类型签名放在 Haskell 的实例声明中?
我喜欢在代码中为所有顶级定义添加类型签名。然而,实例声明中的类型签名似乎是不允许的,如果我放了一个,我会从 GHC 收到“类型签名错误”错误。为什么会这样呢?为什么 GHC 不能检查类型签名是否与其预期相同,如果不同则拒绝(或警告)?
I like to put type signatures for all top-level definitions in my code. However, type signatures in instance declarations don't seem to be allowed, and if I put one I get a "Misplaced type signature" error from GHC. Why is this so? Why can't GHC check if the type signature is the same as what it was expecting, and reject (or warn) if it isn't?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以使用[新] -XInstanceSigs,这对于将类型变量引入作用域特别有用。您可以在 中找到更多信息官方文档。
You can add type signatures for instances using [the new] -XInstanceSigs, which is especially useful for bringing type variables in scope. You can find more information in the official docs.
这里的大多数其他答案都很旧......现在有一个语言扩展:
将以下内容粘贴在文件顶部:
Most of the other answers here are pretty old... there's now a language extension:
stick the following at the top of your file:
如果您确实需要类型声明,则可以在实例主体之外单独创建函数。
You can create the functions separately, outside the instance body, if you really want the type declarations.
由于签名是类定义的一部分,因此实例声明中的类型签名将是重复的签名。我认为原则上允许重复签名没有问题,但一般允许没有什么好处,而且禁止更简单。因此,语言定义表明每个实体最多可以有一个类型签名。在实例声明中允许签名的功能还没有被太多要求,因此没有扩展允许它。如果您确实想要这样做,可以在 GHC trac< 上提出功能请求/a>.如果它得到足够的兴趣,它可能会被实施(但我预计需求不会很高)。
Since the signature is part of the class definition, a type signature in an instance declaration would be a duplicate signature. I don't think there's a problem with allowing duplicate signatures in principle, but there's no advantage in allowing them generally, and it's simpler to disallow them. So the language definition says there can be at most one type signature per entity. The feature of allowing signatures also in instance declarations hasn't been asked for much, so there's no extension allowing it. If you really want that, you can raise a feature request on the GHC trac. If it gets enough interest, it may be implemented (but I don't expect the demand to be high).
无论如何,该类型都是冗余的,人们通常希望避免冗余。
在 Frege 中,仍然允许为实例成员编写类型签名。它们被检查然后扔掉。当然,立即禁止它们会更容易。
In any case, the type is redundant and one normally wants to avoid redundancies.
In Frege, it is nevertheless allowed to write type signatures for instance members. They are checked and then thrown away. It's of course easier to forbid them right away.
自GHC 9.2.1。
这是从支持 GHC2021< 的 GHC 9.2.1 开始的/a>,默认启用一些扩展,其中
InstanceSigs
扩展。以下是文档中的示例:
请注意,在大多数情况下,实例中的类型签名是多余的。文档提到了添加它们的这些可能的动机:
使用类型检查器来确认推断的类型与程序员期望的相匹配(这是用户发布原始问题给出的动机)
作为记录代码的一种方式
将作用域类型变量引入作用域
关于 Haskell 中实例声明中允许类型签名的历史
此功能起源于 StackOverflow 问题。
发布该问题的用户创建了一个问题单,就像他在 2011 年提出问题一样。第二天,Dan Burton 还 创建了一个工单,第一个工单作为重复项被关闭。又一天后,Simon Peyton Jones插话< /a> 并提到他自己也想要这种可能性。他在同一天勾勒出实施方案,并在 7 天后提交之后。该扩展已添加到 GHC 7.6 中。它在 2021 年 10 月发布的 GHC 9.2.1 中默认启用。
注意:PureScript 2017 年添加了该扩展。
Allowing type signatures in instance declarations is enabled by default since GHC 9.2.1.
This follows from GHC 9.2.1 supporting GHC2021, which enables some extensions by default, among these the
InstanceSigs
extension.Here's an example from the documentation:
Note that type signatures in instances are redundant in most cases. The documentation mentions these possible motivations for adding them:
using the type checker to confirm that the inferred type matches what the programmer expects (this is the motivation the user posting the original question gives)
as a way to document the code
bringing scoped type variables into scope
On the history of allowing type signatures in instance declarations in Haskell
This feature has its origins in this StackOverflow question.
The user posting the question created an issue ticket the same he asked the question in 2011. The day after, Dan Burton also created a ticket, and the first ticket was closed as a duplicate. Another day later Simon Peyton Jones chimed in and mentioned him having wanted this possibility himself. He sketched out the implementation the same day and made the commit seven days later. The extension was added to GHC 7.6. It was enabled by default in GHC 9.2.1, which was released in October 2021.
Note: PureScript added the extension in 2017.