functional-programming - 如何直接将 val 绑定到 SML 中的选项值?
问题描述
val SOME i = Int.fromString e
我的代码上有这样一行,smlnj 向我显示了这个警告
vm.sml:84.7-84.32 Warning: binding not exhaustive
SOME i = ...
这是不好的做法吗?我应该使用函数来处理选项还是我错过了什么?
解决方案
如果您只是在处理一个您将运行一次的小脚本,这不一定是不好的做法:如果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
,您可以引发自定义异常来解释发生了什么问题以及用户如何修复它。 - 对于需要更好的错误处理的长寿程序,您应该
NONE
通过对 的结果进行模式匹配来尊重这种情况fromString
,这会迫使您提出某种错误处理行为。
推荐阅读
- angular - 无法更改 Ag-grid 中的图标
- firebase - 具有多个 where 子句的集合组的 Cloud Firestore 索引
- python - 根据比较其他两个列表的结果更新列表
- editor - Shopware 6 将自定义类添加到文本编辑器中的标题标签
- javascript - 将纬度和经度值转换为地名并显示?
- azure - 如何通过 Graph API 从 MS Teams 中恢复通话记录信息
- angular - 如何使用从 HttpClient (Angular) 获得的数据进行排序创建 mat-table
- python - 为什么列表列表的 zip() 会输出这样的结果?
- angular - 如何使用 Prime NG 在条件下选择单选按钮
- amazon-web-services - AWS S3 - java.net.UnknownHostException:repo-user-bucket.s3.us-west-2.amazonaws.com