bel*_*ace 1 error-handling haskell types
我对Haskell生成类型错误消息的方式感兴趣.特别是,我对它建议用户可能想要修复的程序表达式的方式感兴趣,以便错误消失.示例应该使这更清楚.考虑第一个例子.
main = zprint 2
zprint x = putStrLn x
Run Code Online (Sandbox Code Playgroud)
相应的错误消息是:
No instance for (Num String)
arising from the literal `2'
Possible fix: add an instance declaration for (Num String)
In the first argument of `zprint', namely `2'
In the expression: zprint 2
In an equation for `main': main = zprint 2
Run Code Online (Sandbox Code Playgroud)
我解释这个的方式是编译器告诉我应该修复传递的参数2,或者整个函数调用zprint 2,甚至是整个函数调用main = zprint 2,但它会报告putStrLn说我以错误的方式使用它并且我应该使用其他一些功能.同样,我们有以下示例:
main = zprint 2
idn x = x
zprint x = putStrLn (idn x)
Run Code Online (Sandbox Code Playgroud)
消息是一样的:
No instance for (Num String)
arising from the literal `2'
Possible fix: add an instance declaration for (Num String)
In the first argument of `zprint', namely `2'
In the expression: zprint 2
In an equation for `main': main = zprint 2
Run Code Online (Sandbox Code Playgroud)
但是,我们也可以改变第二行,idn x = show x现在程序输入很好.因此,我可以在Haskell列出这些表达式的方式中看到模式,但我希望看到实际的算法,如果它是在某处写下来的,而不是编译器源代码.请注意,我不是Haskell的专家,更像是OCaml人.我使用的GJC版本是7.4.1.
因此,我可以在Haskell列出这些表达式的方式中看到模式,但我希望看到实际的算法,如果它是在某处写下来的,而不是编译器源代码.
没有正式的错误报告算法,它实际上是编译器实现的工程细节,不同的Haskell编译器以不同的方式处理它.所以我担心如果你想了解GHC的细节,唯一的方法就是阅读编译器中的文字Haskell或者Trac wiki上的SPJ注释.
就像BenjaminKovach所说的那样,算法和错误报告与你在香草Hindley Milner中所做的并没有太大的不同.类型检查器跟踪位置信息,当统一者未能找到解决方案时,它会报告产生失败约束的术语的出处.一个小细节是它还尝试对错误消息类型中的自由变量应用可用的部分解决方案.
类型系统本身是HM(X)的演化(参见类型和编程语言高级主题的第10章).概述类型检测器的最新论文是OutsideIn(X),它或多或少地说它在最新的GHC中的工作原理是一些流血的工作.