关于sml zip函数的几个问题

Few questions about sml zip function

我是 sml 的新手,现在我正在尝试定义一个 zip 函数,它将两个列表作为一个元组。 这是代码。 我成功了,但我有几个问题

exception Mismatch;
fun zip ([],[])    = []
| zip ((x::xs),(y::ys)) = (x, y)::zip (xs, ys)
| zip (_, _) = raise Mismatch;

我可以在 zip 函数中定义异常吗,比如 let in end,我试过了,但总是报错。

另一个问题是第二个模式匹配,我写了

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

也给了我错误。

Zip采用元组,但每个元素都是列表,为什么我不能像其他列表一样使用[x::xs]?

最后一个问题,在模式匹配中,顺序重要吗?我想是的,我更改顺序并出错,只是想确定

谢谢

永远不要在 let ... in ... end* 中定义异常。它使得无法通过 let-表达式之外的名称捕获它。

*:如果您不打算让它从 let 表达式中转义也没关系,但您确实打算在这里这样做。

关于你的另一个问题:

当你写 [...] 时,SML 编译器将其理解为 "The list containing ...."

例如,[1] 是包含 1 的列表,[4, 6, 2] 是包含 462 的列表,以及等等。

当你写 x :: xs 时,SML 编译器将其理解为 "The list starting with x, followed by the list xs."

例如1 :: [] 是以 1 开头的列表,后面是空列表,4 :: [6, 2] 是以 4 开头的列表,后面是 62,依此类推.

现在,当你写 [x :: xs] 时,你是在做两者的结合,SML 将其理解为:"The list containing the list starting with x, followed by xs."

因此,通过写 [...] 而不是 (...),您是在另一个列表中请求一个列表。这不是你想要的。

最后一个问题:是的,顺序很重要。模式按自上而下的顺序检查。因此,

fun foo _ = 4
  | foo 4 = 5

将始终 return 4,而

fun foo 4 = 5
  | foo _ = 4

将 return 5 当给出 4.