【问题标题】:Few questions about sml zip function关于sml zip功能的几个问题
【发布时间】:2015-10-09 08:03:11
【问题描述】:

我是 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]?

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

谢谢

【问题讨论】:

    标签: list zip pattern-matching tuples sml


    【解决方案1】:

    您永远不应该在let ... in ... end* 中定义异常。这使得在let-表达式之外通过名称来捕获它是不可能的。

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

    至于你的其他问题:

    当您编写[...] 时,SML 编译器将其理解为“包含... 的列表。”

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

    当您编写x :: xs 时,SML 编译器将其理解为“以x 开头的列表,后跟xs 的列表。”

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

    现在,当您编写[x :: xs] 时,您是在将两者结合起来,SML 将其理解为:“包含以x 开头的列表的列表,后跟xs。”

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

    对于您的最后一个问题:是的,订单很重要。模式以自上而下的顺序检查。因此,

    fun foo _ = 4
      | foo 4 = 5
    

    将始终返回4,而

    fun foo 4 = 5
      | foo _ = 4
    

    当给定4时将返回5

    【讨论】:

    • 非常感谢您的解释,所以[x::xs]表示列表中有两个元素,x和xs?
    • x::xs 表示包含 1 个或多个元素的列表。 x 是一个元素,xs 是剩余的列表。
    猜你喜欢
    • 2020-03-21
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 2011-08-24
    • 2013-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多