【发布时间】:2020-04-15 20:12:02
【问题描述】:
val SOME i = Int.fromString e
我的代码中有这样一行,smlnj 向我显示此警告
vm.sml:84.7-84.32 Warning: binding not exhaustive
SOME i = ...
这是不好的做法吗?我应该使用函数来处理选项还是我遗漏了什么?
【问题讨论】:
标签: functional-programming sml smlnj
val SOME i = Int.fromString e
我的代码中有这样一行,smlnj 向我显示此警告
vm.sml:84.7-84.32 Warning: binding not exhaustive
SOME i = ...
这是不好的做法吗?我应该使用函数来处理选项还是我遗漏了什么?
【问题讨论】:
标签: functional-programming sml smlnj
如果您只是在编写一个只运行一次的小脚本,这不一定是坏习惯:如果Int.fromString e 失败(并返回NONE 而不是SOME _),那么值绑定将失败并且将向适当的处理程序引发异常(或者如果没有处理程序,程序将退出)。要禁用此警告,您可以运行顶级语句(适用于 SML-NJ 110.96):Control.MC.bindNonExhaustiveWarn := false;。
作为替代方法,您可以抛出自定义异常:
val i =
case Int.fromString e
of SOME i => i
| NONE => raise Fail ("Expected string value to be parseable as an int; got: " ^ e)
应以适合e 值来源的方式编写异常消息。 (如果e来自命令行输入,程序应该告诉用户那里应该有一个数字;如果e来自一个文件,程序应该告诉用户哪个文件格式不正确以及格式错误在哪里找到了。)
另一种选择:如果你的程序需要长时间运行并建立大量状态,那么一旦用户输入格式错误的字符串后程序就崩溃了,这对用户来说不是很友好在命令行上。 (在这种情况下用户会非常难过,因为他们在程序中建立的所有状态都将丢失。)在这种情况下,您可以重复从标准输入读取,直到用户输入可以解析为 int 的输入.顺便说一句,这或多或少是 SML/NJ REPL 所做的:而不是像 val SOME parsedProgram = SMLofNJ.parse (getUserInput ()) 这样的东西,它想要做类似的事情:
fun getNextParsedProgram () =
case SMLofNJ.parse (getUserInput ())
of NONE => (print "ERROR: failed to parse\n"; getNextParsedProgram ())
| SOME parsedProgram => parsedProgram
总之,
e 会是一个不可解析的字符串的程序,您可以引发一个自定义异常来解释问题所在以及用户如何修复它。fromString 的结果进行模式匹配来尊重NONE 的情况,这会迫使您提出某种错误处理行为。 【讨论】: