虚拟类型SML

时间:2017-11-03 04:44:20

标签: list sml

我试图在这里做一切,但什么都没发生。我在没有空列表的情况下调用它时代码工作正常,但是一旦我将空列表[]出错就会出错。它会弹出“虚拟类型”'警告和以下代码的一些错误:

fun zip(xs1, x2) =
    case xs1 of
        [] => []
        | (h1::t1) => (case x2 of
                            [] => []
                            |   (h2::t2) => (h1, h2) ::zip(t1,t2));

输出应该是由元组创建的列表,元组是具有较短列表长度的输入列表的头部。正如您在图片中看到的那样,代码本身没有错误,至少不是编译器识别的错误,就在我用空列表调用函数时。

老实说,我不知道那里发生了什么。有人可以向我解释这种类型的错误意味着什么,以及如何修复代码不具备它?

1 个答案:

答案 0 :(得分:1)

在您第一次尝试时,它会正确拉链。在第二次尝试中,您忘记了两个列表之间的逗号。在您的第三次尝试中,您正在成功,但由于第一个参数在顶级是多态的,因此您遇到了 value restriction

更漂亮的zip版本:

fun zip ([], _ys) = []
  | zip (_xs, []) = []
  | zip (x::xs, y::ys) = (x,y)::zip (xs, ys)

更短的等效版本:

fun zip (x::xs, y::ys) = (x,y)::zip (xs, ys)
  | zip _ = []

来自Moscow ML's ListPair module的邮件的尾递归版本:

fun zip (xs, ys) =
    let fun helper (x::xr, y::yr, result) = helper (xr, yr, (x,y)::result)
          | helper (_, _, result) = List.rev result
    in zip' (xs, ys, []) end