【问题标题】:What are nested patterns?什么是嵌套模式?
【发布时间】:2018-10-08 17:56:42
【问题描述】:

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

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

另外,我不明白 nested patternnested case-expression 有什么不同,我能举一些关于这些事情的例子吗?

【问题讨论】:

    标签: sml smlnj


    【解决方案1】:

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

    ([], [], []) 是一个嵌套模式,因为(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 表达式。具有嵌套模式的版本不是嵌套的 case 表达式,因为只有一个 case 表达式 - 彼此之间没有多个。

    【讨论】:

      【解决方案2】:

      如果我们将函数分解为咖喱风格,也许会有所帮助, 没有嵌套模式, 在下面的 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 关键字时,很容易看到每个单独的模式, 每个 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
      

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

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

      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
      

      【讨论】:

        【解决方案3】:

        什么是嵌套模式?

        pattern 中的pattern 是嵌套模式。


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

        | (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*)
            | ...
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-03-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-10
          • 1970-01-01
          • 1970-01-01
          • 2016-05-06
          相关资源
          最近更新 更多