什么是嵌套模式?

时间:2018-10-08 17:56:43

标签: sml smlnj

什么是嵌套模式?我不明白为什么以下代码具有嵌套模式:

exception BadTriple

fun zip3 list_triple =
    case list_triple of
         ([],[],[]) => []
       | (hd1::tl1,hd2::tl2,hd3::tl3) => (hd1,hd2,hd3)::zip3(tl1,tl2,tl3)
       | _ => raise BadTriple

fun unzip3 lst =
    case lst of
         [] => ([],[],[])
       | (a,b,c)::tl => let val (l1,l2,l3) = unzip3 tl
                        in
                          (a::l1,b::l2,c::l3)
                        end

我也无法理解嵌套模式嵌套案例表达之间的区别是什么?

3 个答案:

答案 0 :(得分:5)

嵌套模式是包含其他非平凡模式的模式(其中“非平凡”是指“不是变量或通配符模式”)。

([], [], [])是一个嵌套模式,因为(p1, p2, p3)是一个模式(匹配的元组),而[]也是一个模式(匹配的空列表),这里将其应用于三倍。同样,(hd1::tl1, hd2::tl2, hd3::tl3)是嵌套模式,因为(p1, p2, p3)是模式,而hd1::tl1hd2::tl2hd3::tl3也是模式(匹配非空列表)。

一种表达没有嵌套模式的东西的方法是将内部模式移动到它们自己的case表达式中(尽管我不建议这样做,因为如您所见,这会使代码复杂得多) :

case list_triple of
(x, y, z) =>
  case x of
  [] =>
    case y of
    [] =>
      case z of
      [] => []
      | _ => raise BadTriple
    | _ => raise BadTriple
  | hd1 :: tl1 =>
    case y of
    [] => raise BadTriple
    | h2 :: tl2 =>
      case z of
      [] => raise BadTriple
      | h3 :: tl3 =>
        (hd1,hd2,hd3)::zip3(tl1,tl2,tl3)

这是一个嵌套的case表达式,因为我们有一个case表达式包含其他case-expressions。带有嵌套模式的版本不是嵌套的case表达式,因为只有一个case表达式-彼此之间没有多个。

答案 1 :(得分:1)

如果我们将功能分解为咖喱风格,可能会有所帮助, 没有嵌套模式 在下面的foo函数中,只有3个(非嵌套)模式,

fun foo [] [] [] = []
  | foo (hd1::tl1) (hd2::tl2) (hd3::tl3) = (hd1, hd2, hd3)::zip3(tl1, tl2, tl3)
  | foo _ _ _ = raise BadTriple
and zip3 (l1, l2, l3) = foo l1 l2 l3

当我们使用as关键字时,很容易看到每个单独的模式, 每个右侧的是一个模式。

fun zip3 (l1 as [], l2 as [], l3 as []) = []
  | zip3 (l1 as hd1::tl1, l2 as hd2::tl2, l3 as hd3::tl3) = (hd1, hd2, hd3)::zip3(tl1, tl2, tl3)
  | zip3 _ = raise BadTriple

那么,为什么我们要考虑这种嵌套呢?

我们可以为初始参数 list_triple 添加as, 并看到我们实际上在一个模式中有多个模式。

fun zip3 (list_triple as (l1 as [], l2 as [], l3 as [])) = []
  | zip3 (list_triple as (l1 as hd1::tl1, l2 as hd2::tl2, l3 as hd3::tl3)) = (hd1, hd2, hd3)::zip3(tl1, tl2, tl3)

没有as和未使用的变量,它将看起来更好。

fun zip3 ([], [], []) = []
  | zip3 (hd1::tl1, hd2::tl2, hd3::tl3) = (hd1, hd2, hd3)::zip3(tl1, tl2, tl3)
  | zip3 _ = raise BadTriple

答案 2 :(得分:1)

  

什么是嵌套模式?

模式中的模式是嵌套模式。


  

我不明白为什么它是嵌套模式

| (hd1::tl1,hd2::tl2,hd3::tl3) => ...
  • 模式在这里:(list1, list2, list3)

  • 嵌套模式此处:list1 -> hd1::tl1list2 -> hd2::tl2list3 -> hd3::tl3


| (a,b,c)::tl =>
  • 模式在这里:tuple::t1

  • 嵌套模式在这里:tuple -> (a, b, c)

  

我也无法理解嵌套模式和嵌套case-expression之间的区别是什么?


它们是两件事。上面已经说明了嵌套模式。至于嵌套的 case-expression

case something of              (*case here*)
| pattern =>
    case pattern of                (*nested case here*)
    | ...