SML:多案例陈述

SML:多案例陈述,sml,Sml,我怎么能有多个case语句彼此不交错呢。 例如,一个玩具示例: fun multi_cases(xs) = case xs of [] => 5 | x::ys => case x of 1 => 2 |_ => 3 | x::[] => case x of 1 => 5

我怎么能有多个case语句彼此不交错呢。 例如,一个玩具示例:

 fun multi_cases(xs) =
     case xs of
       [] => 5
      | x::ys => case x of
                    1 => 2
                   |_ => 3
      | x::[] => case x of
                    1 => 5
                    | _ => 7
 ;

stdIn:59.17-64.28 Error: types of rules don't agree [overload conflict]
  earlier rule(s): [int ty] -> [int ty]
  this rule: [int ty] list -> [int ty]
  in rule:
    :: (x,nil) =>
      (case x
        of 1 => 5
         | _ => 7)
最后两个case语句混淆了,我如何告诉SML它们确实是两个独立的case语句,而不是case x的1=>2的延续/独立分支


下面的答案中指出的上述模式在通用性方面存在问题。

此代码有两个不同的问题:

  • 正如John链接到的问题所说,case of在语法上有点棘手,因为它们的case语句列表从未“停止”。也就是说,您的代码实际上被解析为:

    fun multi_cases xs =
        case xs of
             [] => 5
           | x::ys => case x of
                           1 => 2
                         | _ => 3
                         | x::[] => case x of
                                         1 => 5
                                       | _ => 7
    
    这是毫无意义的,因为第三个模式应该属于的外壳,而不是内部(的内部外壳将
    x
    作为int处理,而外部将
    x:[]
    作为int列表处理)

    由于缩进并没有积极地帮助编译器实现预期的含义,所以使用括号“阻止”s的情况,就像那篇文章所说的那样,是一个解决办法:

    fun multi_cases xs =
        case xs of
             [] => 5
           | x::ys => (case x of
                           1 => 2
                         | _ => 3)
           | x::[] => (case x of
                            1 => 5
                          | _ => 7)
    
    或者,您可以将的外部大小写转换为函数参数本身的匹配,并将的内部大小写与之混合,因为单个模式匹配允许任意深度的匹配:

    fun fun_cases [] = 5
      | fun_cases [1] = 5
      | fun_cases [_] = 7
      | fun_cases (1::_) = 2
      | fun_cases (_::_) = 3
    
  • 您的两个案例重叠,因为
    x::xs
    是比
    x::[]
    更通用的模式。也就是说,它还通过将
    xs
    设置为
    []
    来覆盖列表
    x::[]
    。您可以通过以下两种方式之一解决此问题:

  • 首先列出最不通用的模式,例如

    case xs of
         [] => 5
       | [x] => ...
       | x::_ => ...
    
  • 通过指定列表应至少包含两个元素,将
    x::xs
    常规模式转换为不太常规的模式:

    case xs of
         x :: _ :: _ => ...
       | [x] => ...
       | [] => ...
    

  • 此代码有两个明显的问题:

  • 正如John链接到的问题所说,case of在语法上有点棘手,因为它们的case语句列表从未“停止”。也就是说,您的代码实际上被解析为:

    fun multi_cases xs =
        case xs of
             [] => 5
           | x::ys => case x of
                           1 => 2
                         | _ => 3
                         | x::[] => case x of
                                         1 => 5
                                       | _ => 7
    
    这是毫无意义的,因为第三个模式应该属于的外壳,而不是内部(的内部外壳将
    x
    作为int处理,而外部将
    x:[]
    作为int列表处理)

    由于缩进并没有积极地帮助编译器实现预期的含义,所以使用括号“阻止”s的情况,就像那篇文章所说的那样,是一个解决办法:

    fun multi_cases xs =
        case xs of
             [] => 5
           | x::ys => (case x of
                           1 => 2
                         | _ => 3)
           | x::[] => (case x of
                            1 => 5
                          | _ => 7)
    
    或者,您可以将的外部大小写转换为函数参数本身的匹配,并将的内部大小写与之混合,因为单个模式匹配允许任意深度的匹配:

    fun fun_cases [] = 5
      | fun_cases [1] = 5
      | fun_cases [_] = 7
      | fun_cases (1::_) = 2
      | fun_cases (_::_) = 3
    
  • 您的两个案例重叠,因为
    x::xs
    是比
    x::[]
    更通用的模式。也就是说,它还通过将
    xs
    设置为
    []
    来覆盖列表
    x::[]
    。您可以通过以下两种方式之一解决此问题:

  • 首先列出最不通用的模式,例如

    case xs of
         [] => 5
       | [x] => ...
       | x::_ => ...
    
  • 通过指定列表应至少包含两个元素,将
    x::xs
    常规模式转换为不太常规的模式:

    case xs of
         x :: _ :: _ => ...
       | [x] => ...
       | [] => ...
    

  • 这些括号的作用是什么?他们是否添加了某种模式匹配?+1问题,语言中是否有规则可以帮助您首先定义更一般的模式?因为不太一般的模式不匹配。什么括号?我不知道你所说的语言规则是什么意思。堆栈溢出实际上不适合在评论中来回讨论,也不适合对子问题进行连续阐述。我建议你读一本,选一门有助教的课程,或者读一些特定的科目,比如。这些括号是做什么的?他们是否添加了某种模式匹配?+1问题,语言中是否有规则可以帮助您首先定义更一般的模式?因为不太一般的模式不匹配。什么括号?我不知道你所说的语言规则是什么意思。堆栈溢出实际上不适合在评论中来回讨论,也不适合对子问题进行连续阐述。我建议你读一本书,选一门有助教的课程,或者读一些特定的学科,比如。