Unable to select the right combinator for parsing and deal with it in Scala

I have this code that includes a scala Parsersclass:

trait SomeTrait extends SomeTrait2 {
  def myParse = {
    phrase(rep(
            ElemName(Some("http://someUri/"), "someNode1") ~       //compiles well, but fails sometimes at runtime
            ElemName(Some("http://someUri/"), "someNode2") ^^
            {
              case p1 ~ p2 ⇒  //......
            }) ^^
            {
              case p1 ⇒  // ....
            })
  }
}

Where

case class ElemName(namespace: Option[String], name: String) {
   // .....
}

Usually " someNode1" and " someNode2" exist in the input soap line (which is not specified here, but it does not matter). However, sometimes any of them may exist or even none of them, in which case it crashes at runtime.

<items>
  <subItems>
    <someNode1 val1="123" val2="456" />
    <someNode1 val1="123a" val2="456c" />
    <someNode1 val1="123b" val2="456d" />
    <someNode2 val1="123" val2="456" />
  </subItems>
  <subItems>
    <someNode2 val1="123cd" val2="456de" />
  </subItems>
  <subItems>
  </subItems>
  <subItems>
    <someNode1 val1="777" val2="888" />
  </subItems>
<items>

I have to handle this. So I did:

trait SomeTrait extends SomeTrait2 {
  def myParse = {
    phrase(rep(
      ElemName(Some("http://someUri/"), "someNode1") |          // should work
      ElemName(Some("http://someUri/"), "someNode2") ^^ 
      {
        case p1 ~ p2 ⇒  //......
      }) ^^
      {
        case p1 ⇒  // ....
      })

      //or, I'm not sure which one to choose
      //ElemName(Some("http://someUri/"), "someNode1") |||      // should work also
      //ElemName(Some("http://someUri/"), "someNode2") ^^ 
  }
}

and this should work, as I understand it. However, at the moment, it no longer compiles, as it says:

constructor cannot be instantiated to expected type;
[error]  found   : SomeTrait.this.~[a,b]
[error]  required: ElemName
[error]           case p1 ~ p2 ⇒ {
[error]                   ^
[error] one error found

I believe that I should replace the case p1 ~ p2 with something else.

+4
1

, | ||| . :

a | b a, , , b, a ||| b a b , . , - , . , p1 not p1 ~ p2. , :

phrase(rep(
  ElemName(Some("http://someUri/"), "someNode1").? ~
  ElemName(Some("http://someUri/"), "someNode2").? ^^ 
  {
    case Some(p1) ~ Some(p2) ⇒  //......
    case Some(p1) ~ None => //.....
    case None ~ Some(p2) => //.....
  })
+1

All Articles