我正在嘗試為串列操作實作擴展。它檢查串列是否為空;如果引數不是一個串列,它應該產生一個錯誤。我使用 (>>=) 函式處理后端的錯誤傳播。我在下面實作的空函式首先使用輔助函式 (list_of_listVal) 檢查值是否是串列。然后如果串列為空回傳true,否則回傳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)?
uj5u.com熱心網友回復:
問題是您正在將串列解構為頭部和尾部(或分別為第一個元素和串列的其余部分),這當然假設串列中至少有一個元素,因此出現警告和例外當遇到空串列時。
你有什么期望v1,并v2在這里,當給出的空單?
此外,在將其與空串列進行比較之前,您會以完全相同的方式再次將頭部和尾部放在一起,而不以任何其他方式使用它。這永遠不會是真的,因為您剛剛構建了一個至少包含一個元素的串列。
然后,解決方案是簡單地不解構,然后立即重新組合串列。替換v1::v2為vs(或您選擇的任何其他識別符號)。也不需要將串列包裝在 中ListVal,因為它只是間接的。
fun vs ->
if vs = [] then
return (BoolVal true)
else
return (BoolVal false)
然后,您可以通過 using 使這更加簡潔function,它允許直接在函式引數上進行模式匹配而無需命名:
function | [] -> return (BoolVal true)
| _ -> return (BoolVal false)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/322315.html
