我不确定在main = do ...
内创建实例以响应用户输入read
报告错误的正确方法。
具体来说,我有一个构造函数来验证其参数并以通常的方式报告错误
-- ...
Right cfg -> cfg
Left err -> error (show err)
以及使用此构造函数的read
的实现。但是在我的实现中,我有一个神秘的注释(继承自一些很久以前的研究,我已经忘记了),它删除了错误信息
instance Read ... where
readsPrec _ i = case ...
Right cfg -> [(cfg, "")]
Left _ -> [] -- Loses error information, but conforms to specification of 'readsPrec' in 'Read'
以便我的命令行解析器
main :: IO ()
main = do
... read
仅将构造函数生成的所有错误报告为仅
Prelude.read: no parse
如果我忽略我的神秘评论,而是有
Left err -> error (show err)
在构造函数中,然后我得到报告给用户的完整错误信息:
script: Detailed error information here
CallStack (from HasCallStack):
error, called at ./Pkg/Module.hs:371:57 in main:Pkg.Module
(尽管对于堆栈和行信息,我宁愿不在此上下文中报告)。
所以我有三个相关的问题:
- 实际上有什么理由不使用
Left err -> error (show err)
报告read
的完整错误信息吗? - 如果是这样并且那里需要类似
Left err -> []
的东西,如何在命令行报告read
或构造函数错误?
和(不那么重要)
- 从
main = do ...
中的read
报告时如何摆脱堆栈信息?
- 是的:纯代码无法捕获
error
调用。从纯代码中知道read
(好吧,reads
)失败通常是有用的。 - 使用与
Read
不同的类进行分析,以便更清楚地报告错误。每个流行的解析器组合器库都有良好的错误报告工具。 - 使用富有想象力的名称
errorWithoutStackTrace
。