2017-02-09 104 views
0

如何拥有多个不相互交错的陈述陈述? 例如玩具例子:SML:多个案例陈述

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语句,而不是1情况下,x的延续/独立分支=> 2 ...

上面的答案在下面的答案中指出了它们的一般性问题。

+0

[巢式病例中陈述的可能的复制SML](http://stackoverflow.com/questions/14708732/nested-case-statements-in-sml) –

回答

2

这段代码有两个明显的问题:

  1. 由于问题Nested case statements in SML约翰链接到说,案例的 s为语法有点棘手,因为他们的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 list)。

    由于您的压痕不积极帮助朝本意编译器,使用括号从缠绕“停止” 病例的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 
    
  2. 您的两个案例重叠,因为x::xs是比x::[]更通用的模式。也就是说,它还通过将xs设置为[]来覆盖列表x::[]。您可以通过以下两种方式之一修复该问题:

    1. 首先列出最不常用的图案,例如,

      case xs of 
          [] => 5 
          | [x] => ... 
          | x::_ => ... 
      
    2. 通过指定该列表应当具有至少两个元素作出这样x::xs一般图案划分为以下一般之一:

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

这些括号是做什么的?他们是否添加了某种模式匹配? – Har

+0

+1问题,在语言中是否有规则可以帮助您首先定义更一般的模式?因为较不普遍的模式不匹配。 – Har

+0

什么括号?我不确定你的语言规则是什么意思。堆栈溢出并不真正适合评论中的前后讨论,也不适合对子问题进行持续的阐述。我建议你阅读[标准ML入门级书籍](https://www.amazon.com/Introduction-Programming-International-Computer-Science/dp/0201398206),参加一门有TA的课程,或者阅读有关特定主题的内容,例如[类型推断/统一](http://www.cs.cornell.edu/courses/cs312/2005sp/lectures/lec22.asp)。 –