我是sml的新手,现在我正在尝试定义一个zip函数,它将两个列表作为元组。 这是代码。 我得到了它的工作,但我有几个问题
exception Mismatch;
fun zip ([],[]) = []
| zip ((x::xs),(y::ys)) = (x, y)::zip (xs, ys)
| zip (_, _) = raise Mismatch;
我可以在zip函数中定义异常,比如让我们尝试,但总是得到错误。
另一个问题是第二次模式匹配,我写了
zip ([x::xs],[y::ys]) = (x, y)::zip (xs, ys)
也给了我错误。
Zip取一个元组,但每个元素都是list,为什么我不能像其他列表一样使用[x :: xs]?
最后一个问题,在模式匹配中,订单是否重要?我认为是,我改变顺序并得到错误,只是想确保
由于
答案 0 :(得分:1)
您永远不应在let ... in ... end
*内定义例外。它使得在let
- 表达式之外的名称无法捕获它。
*:如果你不打算让它从let
- 表达式中逃脱,那没关系,但你确实打算在这里做到这一点。
至于你的另一个问题:
当您编写[...]
时,SML编译器将其理解为"包含...
的列表。"
例如,[1]
是包含1
的列表,[4, 6, 2]
是包含4
,6
和2
的列表,依此类推
当您编写x :: xs
时,SML编译器将其理解为"列表以x
开头,后跟列表xs
。"
E.g。 1 :: []
是以1开头的列表,后跟空列表,4 :: [6, 2]
是以4开头的列表,后跟6
和2
,依此类推
现在,当您编写[x :: xs]
时,您正在对两者进行组合,并且SML将其理解为:"包含以x
开头的列表的列表, xs
。"
因此,通过撰写[...]
而不是(...)
,您需要在另一个列表中寻找列表。这不是你想要的。
对于你的最后一个问题:是的,订单很重要。模式以自上而下的顺序进行检查。因此,
fun foo _ = 4
| foo 4 = 5
将始终返回4
,而
fun foo 4 = 5
| foo _ = 4
如果给出5
,将返回4
。