异常:Match_failure 在解释器的扩展中能够处理 OCaml 中的列表操作
Exception: Match_failure in an extension of the interpreter to be able to handle the list operations in OCaml
我正在尝试实现列表操作的扩展。它检查列表是否为空;如果参数不是一个列表,它应该产生一个错误。我使用 (>>=) 函数在后端处理错误传播。我在下面实现的空函数首先使用辅助函数 (list_of_listVal) 检查值是否是列表。然后如果列表为空 returns true,否则 returns false。对应代码如下:
| Empty(e1) ->
eval_expr e1 >>=
list_of_listVal >>= fun (v1::v2) ->
if ( ListVal ([]) = ListVal (v1::v2) )
then return @@ BoolVal(true)
else return @@ BoolVal(false)
但是,一旦我 运行 顶层,我就收到了警告。
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
[]
File "src/interp.ml", lines 88-91, characters 24-35:
88 | ........................fun (v1::v2) ->
89 | if ( ListVal ([]) = ListVal (v1::v2) )
90 | then return @@ BoolVal(true)
91 | else return @@ BoolVal(false)
然后当我 运行 下面的代码生成异常时:
utop # interp "empty?(emptylist)";;
Exception: Match_failure ("src/interp.ml", 88, 24).
我不知道如何解决这个问题。有人能指出如何以正确的方式为上面的代码实现列表 (v1::v2) 吗?
问题是您正在将列表解构为头部和尾部(或分别为第一个元素和列表的其余部分),这当然假设列表中至少有一个元素,因此遇到空列表时的警告和异常。
当给定空列表时,您希望 v1
和 v2
在这里是什么?
此外,在将它与空列表进行比较之前,您将以完全相同的方式再次将头部和尾部放在一起,而不以任何其他方式使用它。这永远不可能是真的,因为您刚刚构造了一个至少包含一个元素的列表。
那么解决方案就是不解构然后立即重新组合列表。将 v1::v2
替换为 vs
(或您选择的任何其他标识符)。也没有必要将列表包装在 ListVal
中,因为它只是更间接。
fun vs ->
if vs = [] then
return (BoolVal true)
else
return (BoolVal false)
然后您可以使用 function
使其更加简洁,它允许直接在函数参数上进行模式匹配而无需命名它:
function | [] -> return (BoolVal true)
| _ -> return (BoolVal false)
我正在尝试实现列表操作的扩展。它检查列表是否为空;如果参数不是一个列表,它应该产生一个错误。我使用 (>>=) 函数在后端处理错误传播。我在下面实现的空函数首先使用辅助函数 (list_of_listVal) 检查值是否是列表。然后如果列表为空 returns true,否则 returns false。对应代码如下:
| Empty(e1) ->
eval_expr e1 >>=
list_of_listVal >>= fun (v1::v2) ->
if ( ListVal ([]) = ListVal (v1::v2) )
then return @@ BoolVal(true)
else return @@ BoolVal(false)
但是,一旦我 运行 顶层,我就收到了警告。
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
[]
File "src/interp.ml", lines 88-91, characters 24-35:
88 | ........................fun (v1::v2) ->
89 | if ( ListVal ([]) = ListVal (v1::v2) )
90 | then return @@ BoolVal(true)
91 | else return @@ BoolVal(false)
然后当我 运行 下面的代码生成异常时:
utop # interp "empty?(emptylist)";;
Exception: Match_failure ("src/interp.ml", 88, 24).
我不知道如何解决这个问题。有人能指出如何以正确的方式为上面的代码实现列表 (v1::v2) 吗?
问题是您正在将列表解构为头部和尾部(或分别为第一个元素和列表的其余部分),这当然假设列表中至少有一个元素,因此遇到空列表时的警告和异常。
当给定空列表时,您希望 v1
和 v2
在这里是什么?
此外,在将它与空列表进行比较之前,您将以完全相同的方式再次将头部和尾部放在一起,而不以任何其他方式使用它。这永远不可能是真的,因为您刚刚构造了一个至少包含一个元素的列表。
那么解决方案就是不解构然后立即重新组合列表。将 v1::v2
替换为 vs
(或您选择的任何其他标识符)。也没有必要将列表包装在 ListVal
中,因为它只是更间接。
fun vs ->
if vs = [] then
return (BoolVal true)
else
return (BoolVal false)
然后您可以使用 function
使其更加简洁,它允许直接在函数参数上进行模式匹配而无需命名它:
function | [] -> return (BoolVal true)
| _ -> return (BoolVal false)