受到this reddit discussion的启发,我想知道在理解错误消息方面,帮助初学者的方案和方式方法是否存在任何技术障碍。一个典型的例子是臭名昭着的
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
的类型有多少说法,但我们肯定可以更直接地解决这个问题。
是否还有其他机会根据现实的简化假设重新构建错误消息?请注意,我提出了一个问题,即根据程序员的经验模型更改错误消息的文本:我不是在本地考虑对哪些代码被认为是错误的任何更改(例如,通过假设初学者将使用特殊类型的重载事物,消除歧义。)
后续想法:现有错误消息的文本是否包含足够的信息来支持这种转换,假设一个&#34;配置文件&#34;建模学生?也就是说,一个有进取心的黑客是否可以为ghci
实现一个可懂度增强的后处理器,而不会让总部忙碌的人感到麻烦?
答案 0 :(得分:10)
我不相信为了错误消息而忽略某些功能会有所帮助。
首先,初学者遇到的错误 与其他人有什么不同?仅仅因为我知道如何解释“对于这个荒谬的事物,这显然不是一个数字类型的错误实例”错误并不意味着我不会更加清楚地指出GHC更明确地指出了我所做的那些引起挑衅的事情。这样的消息。
我建议初学者或专家编写实例或任何其他类型的“高级”代码的情况差别很小。然而,初学者将在这种情况下进行编码,而不是经常进行编码,其中包含“从不”的包含下限。
如果有人希望将初学者与语言的奥术角隔离,那么请确保他们根本不会遇到它们。例如(ha,ha),在首次引入语言时,有一个完全避免类型类的论据。
我想不出任何一个更适合初学者的错误信息的情况,只要它不丢弃信息,对其他人来说也不会更愉快。
假设我们在本地假设程序员将声明没有新实例。
假设我们假设程序员将声明没有 orphan 实例,其中类和/或类型由Haskell报告定义。对于初学者来说,这种假设是最切合实际的,事实上,作为一般规则似乎是合理的。
由于编译器错误而添加这样的实例在极少数情况下是合理的。随着匿名编写器monad的明显和无聊的例外(除非我上次检查后已经补救)标准类和类型的孤立实例似乎极不可能,并且只有当一个或另一个应该出现时一个图书馆出乎意料地忽略了一些情况,或者已经陈旧,尘土飞扬,足以早于Applicative
或Foldable
之类的东西。在任何情况下, 想要这样一个实例的任何人都可以安全地假设他们知道他们正在做什么,以解释GHC的错误信息,无论它是什么。
但足够关于那个特定的例子。
是否还有其他机会根据现实的简化假设重新构建错误消息?
非常可能,但我们也远远没有用尽现实复杂假设的空间!
上述实例的重点是通过使用编译器已经可用的信息和检查更大上下文的启发式方法(例如,定义某些事物,以区分上述示例和非孤立实例)错误消息总的来说可以改进。
后续想法:假设“配置文件”为学生建模,现有错误消息的文本是否包含足够的信息来支持此类转换?
除非在最简单和最令人震惊的情况下,我真的看不到这种效果很好,你给出的例子是一个值得注意的例子。它可以改写现有的错误风格,但初学者将从拥有现有消息可能不包含的更详细/明确的信息中受益最多。
考虑另外两个长期困扰初学者的错误信息:关于匹配“刚性类型变量”的抱怨和关于“无限类型”的抱怨。修改可能会有所改善,但是在每个错误消息中包含一个关于多态性的教程之外,它不会对初学者修复他们的代码有多大帮助,除非你能够解释相关的表达式并且输入得足够好,以便具体说明原因。
与检查源代码一起,“翻译”可能有一些支持,但我怀疑直接修改GHC将很快成为最简单的路径。生成错误消息将是一个有趣的扩展点,但我不认为这可以通过GHC现有的插件基础结构来完成。
我认为,任何这一切的最大障碍都不是实施。相反,它是决定哪种启发式方法可以改善错误信息而不是完成相反的操作。没有客观数据的基础,这是一个容易出错(ha,ha)猜谜游戏。收集(主要是中级或新手)Haskell程序员遇到的错误的大型调查,以及最重要的是他们为解决问题所做的实际更改,这将是非常有趣的。
答案 1 :(得分:5)
我相信Haskell的Helium子集是尝试这样做的。自从我尝试了它已经很长时间了,但是IIRC,它产生了比GHC更好的错误信息。