19

This is more of a stylistic question than anything else. Given the following piece of code:

case e1 of                    (* datatype type_of_e1  = p1 | p2 *)
    p1 => case e11 of         (* datatype type_of_e11 = NONE | SOME int *)
              NONE => expr11
            | SOME v => expr12 v
  | p2 => case e21 of         (* datatype type_of_e21 = NONE | SOME string *)
              NONE => expr21
            | SOME v => expr22 v

Is there a way to resolve the types of rules don't agree error caused by trying to pattern match e11 to p2, other than enclosing p1's expression in parenthesis? The p2 pattern has another case statement, to avoid the 'just switch the patterns' answer ;-).

update: changed the code to reflect a more concrete case

slash3r
  • 193
  • 1
  • 7
  • 1
    What is `e2`? Can you provide a complete function? It is an **error**, so it's better to fix it before worrying about coding style. – pad Feb 05 '13 at 13:55
  • @pad: I've updated the code to clear up the confusion. `e2` was the initial name of `e11`, Having changed the code to add a case for `p2` I've forgot the change it's name in the question. The only error I get is if I don't surround in parenthesis the expression for `p1`. – slash3r Feb 06 '13 at 06:36
  • Speaking of coding style, it is good style to have value constructors starting with a capital letter, to avoid any confusion of it being a varaible. Here I', talking about your `p1` and `p2`. – Jesper.Reenberg Feb 06 '13 at 13:31

3 Answers3

19

The answer is "(" and ")". My example:

case e1 of                   
   p1 => ( case e11 of         
              NONE => expr11
              | SOME v => expr12 v )
   | p2 => ( case e21 of         
                NONE => expr21
                | SOME v => expr22 v )

This really works! Cool :) You can try it too.

Beraliv
  • 518
  • 7
  • 20
10

No. The syntactic rules in the Definition of Standard ML state that the match arms of a case expression attempt to maximally consume potential clauses. And since there's no "end case" or similar marker in the language, the parser will merrily eat each of the "| pat => exp" clauses that you feed it until it sees something that terminates a list of match clauses.

Lars Bergstrom
  • 807
  • 7
  • 13
  • Sorry, I was to vague with my code, I've updated it since. My confusion arises from the fact that the `case` expression does consume all of the potential clauses (`e11` being an `option`, `NONE` and `SOME v` will cover all cases, leaving the parser with no option other than ending the `case` expression). – slash3r Feb 06 '13 at 06:44
  • 1
    @slash3r The parser does not know about types. Type checking phase comes-in after the parser is done constructing AST. – lebowski Nov 10 '13 at 20:56
4

Plain and short answer: no. But what's wrong with parentheses?

(Of course, you can also bracket in other ways, e.g. with a 'let', or by factoring into auxiliary functions, but parentheses are the canonical solution.)

Andreas Rossberg
  • 34,518
  • 3
  • 61
  • 72
  • There's nothing wrong with them, I was just hopping that I missed a more elegant work around for this problem. – slash3r Feb 06 '13 at 06:23