17

受此reddit 讨论的启发,我想知道在理解错误消息时,以“Dr Scheme”式的方法来帮助初学者是否存在任何技术障碍。一个典型的例子是臭名昭著的

Prelude> 1 "doesn't"

<interactive>:3:1:
    No instance for (Num ([Char] -> t0))
      arising from the literal `1'
    Possible fix: add an instance declaration for (Num ([Char] -> t0))
    In the expression: 1
    In the expression: 1 "doesn't"
    In an equation for `it': it = 1 "doesn't"

假设我们要做出程序员不会声明新实例的本地假设。确实,在 Haskell 中仅通过 仅与前奏类进行交互可以获得很长的路要走deriving,所以这个假设对于初学者来说并不是不切实际的。在这样的假设下,上述错误消息将是题外话。我们可以改进它吗?我们可能仍然需要弄清楚要对 的类型说多少1,但我们肯定可以更直接地解决这个问题。

是否有其他机会根据现实的简化假设重新构建错误消息?请注意,我是在问一个关于根据程序员经验模型更改错误消息文本的问题:我没有在本地考虑对哪些代码被认为是错误的任何更改(例如,假设初学者将在专业领域使用重载的东西类型,消除歧义)。

一个后续的想法:假设一个“配置文件”对学生进行建模,现有错误消息的文本是否包含足够的信息来支持这种转换?也就是说,一个有进取心的黑客能否在ghci不打扰总部忙碌的人们的情况下实施一个可理解性增强的后处理器?

4

2 回答 2

11

我不相信为了错误消息而忽略某些功能会有所帮助。

一方面,初学者遇到的错误真的和其他人有那么大的不同吗?仅仅因为我知道如何解释“这个显然不是数字类型的荒谬事物的无 Num 实例”错误并不意味着我不会更欣赏 GHC 更清楚地指出我做了什么愚蠢的事情来挑起这样的消息。

我建议初学者或专家编写实例或任何其他类型的“高级”代码的情况差别很小。然而,初学者在这种情况下编码的频率要低得多,包括“从不”的下限。

如果有人希望将初学者与语言的神秘角落隔离开来,那么请确保他们根本不会遇到它们。例如 (ha, ha),当第一次引入语言时,有一个论点是要完全避免类型类。

我想不出任何对初学者更友好的错误消息,只要它不丢弃信息,对其他人也不会更愉快。

假设我们要做出程序员不会声明新实例的本地假设。

假设我们假设程序员不会声明类和/或类型由 Haskell 报告定义的孤儿实例。这个假设对于初学者来说是最现实的,事实上,作为一般规则似乎是合理的。

在极少数情况下,由于编译器错误而添加这样的实例是合理的。除了匿名作家 monad 的明显和令人讨厌的例外(除非自从我上次检查以来已经补救)标准类类型的孤儿实例似乎极不可能,并且只有当库意外忽略了一些时才会出现其中一个或另一个实例, or 已经陈旧且尘土飞扬,足以早于诸如Applicativeor之类的东西的流行Foldable。在任何情况下,任何确实想要这样一个实例的人都可以安全地假设他们知道他们做得足够好来解释 GHC 的错误消息,无论它可能是什么。

但是关于那个特定的例子就足够了。

是否有其他机会根据现实的简化假设重新构建错误消息?

很有可能,但我们也远未耗尽现实复杂假设的空间!

上述关于实例的题外话的要点是,通过使用编译器已经可用的信息和检查更大上下文的启发式方法(例如,在定义某些事物的地方,将上述示例与非孤立实例区分开来),可以改进错误消息一般来说。

一个后续的想法:假设一个“配置文件”对学生进行建模,现有错误消息的文本是否包含足够的信息来支持这种转换?

除了在最简单和最令人震惊的情况下,我真的看不出这个效果很好,你给出的例子是一个值得注意的例子。它可以改写现有的错误风格,但初学者将从现有消息可能不包含的更详细/明确的信息中受益最多。

考虑另外两个长期困扰初学者的错误消息:关于匹配“刚性类型变量”的抱怨,以及关于“无限类型”的抱怨。改写可能会在一定程度上改善这些问题,但如果没有在每条错误消息中包含关于多态性的教程,它不会对初学者修复他们的代码有太大帮助,除非您可以解释相关的表达式并输入足够好的内容以具体说明原因。

连同检查源代码,“翻译器”可能有一些腿,但我怀疑直接修改 GHC 将很快成为最简单的途径。生成错误消息将是一个有趣的扩展点,但我认为这不能通过 GHC 现有的插件基础设施来完成。


我预计,最大的障碍不是实施。相反,这是决定哪种启发式方法可以改善错误消息,而不是相反。没有客观数据的基础,这是一个容易出错(哈哈)的猜谜游戏。对 Haskell 程序员(主要是中级或新手)遇到的错误进行大量调查会非常有趣,最重要的是,他们为解决问题做了哪些实际更改。

于 2012-09-06T14:35:41.087 回答
5

我相信 Haskell 的 Helium子集就是这样做的一个尝试。我已经很久没有尝试过了,但是 IIRC,它产生的错误信息比 GHC 好得多。

于 2012-09-06T09:04:26.893 回答