如何直接将 val 绑定到 SML 中的选项值?
How do I directly make an val binding to an option value in SML?
val SOME i = Int.fromString e
我的代码中有这样一行,smlnj 向我显示了这个警告
vm.sml:84.7-84.32 Warning: binding not exhaustive
SOME i = ...
这是不好的做法吗?我应该使用一个函数来处理这个选项还是我遗漏了什么?
如果您只是在编写一个小脚本,您将 运行 一次,这不一定是不好的做法:如果 Int.fromString e
失败(并且 returns 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
来自文件,程序应该告诉用户哪个文件格式不正确,发现格式错误的地方。)
另一种选择:如果你的程序是长运行ning并且建立了很多状态,那么如果程序在用户在命令行中输入了格式错误的字符串。 (在这种情况下,用户会非常难过,因为他们在程序中建立的所有状态都将丢失。)在这种情况下,您可以重复从 stdin 读取,直到用户输入可以解析为 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
综上所述,
- 对于短期脚本或您不打算经常 运行ning 的脚本,关闭警告是一个不错的选择。
- 对于意外
e
将是无法解析的字符串的程序,您可以提出一个自定义异常来解释出错的原因以及用户如何修复它。
- 对于需要更好的错误处理的长期程序,您应该通过对
fromString
的结果进行模式匹配来尊重 NONE
的情况,这迫使您想出某种排序错误处理行为。
val SOME i = Int.fromString e
我的代码中有这样一行,smlnj 向我显示了这个警告
vm.sml:84.7-84.32 Warning: binding not exhaustive
SOME i = ...
这是不好的做法吗?我应该使用一个函数来处理这个选项还是我遗漏了什么?
如果您只是在编写一个小脚本,您将 运行 一次,这不一定是不好的做法:如果 Int.fromString e
失败(并且 returns 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
来自文件,程序应该告诉用户哪个文件格式不正确,发现格式错误的地方。)
另一种选择:如果你的程序是长运行ning并且建立了很多状态,那么如果程序在用户在命令行中输入了格式错误的字符串。 (在这种情况下,用户会非常难过,因为他们在程序中建立的所有状态都将丢失。)在这种情况下,您可以重复从 stdin 读取,直到用户输入可以解析为 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
综上所述,
- 对于短期脚本或您不打算经常 运行ning 的脚本,关闭警告是一个不错的选择。
- 对于意外
e
将是无法解析的字符串的程序,您可以提出一个自定义异常来解释出错的原因以及用户如何修复它。 - 对于需要更好的错误处理的长期程序,您应该通过对
fromString
的结果进行模式匹配来尊重NONE
的情况,这迫使您想出某种排序错误处理行为。