2012-04-17 1 views
1

matchSeq으로 작성된 이유는 LinearSeq 유형의 경우보다 IndexedSeq 유형에서 다르게 작동할까요? 내게는 아래 코드가 입력 유형에 관계없이 똑같은 일을해야하는 것처럼 보입니다. 물론 그렇지 않거나 묻지 않을 것입니다. 2.9.1 마지막에 실행MatchedError가 LinearSeq이 아닌 IndexedSeq을 수신 할 때

import collection.immutable.LinearSeq 
object vectorMatch { 
    def main(args: Array[String]) { 
    doIt(Seq(1,2,3,4,7), Seq(1,4,6,9)) 
    doIt(List(1,2,3,4,7), List(1,4,6,9)) 
    doIt(LinearSeq(1,2,3,4,7), LinearSeq(1,4,6,9)) 
    doIt(IndexedSeq(1,2,3,4,7), IndexedSeq(1,4,6,9)) 
    doIt(Vector(1,2,3,4,7), Vector(1,4,6,9)) 
    } 

    def doIt(a: Seq[Long], b: Seq[Long]) { 
    try { 
     println("OK! " + m(a, b)) 
    } 
    catch { 
     case ex: Exception => println("m(%s, %s) failed with %s".format(a, b, ex)) 
    } 
    } 

    @annotation.tailrec 
    def m(a: Seq[Long], b: Seq[Long]): Seq[Long] = { 
    a match { 
     case Nil => b 
     case firstA :: moreA => b match { 
     case Nil => a 
     case firstB :: moreB if (firstB < firstA) => m(moreA, b) 
     case firstB :: moreB if (firstB > firstA) => m(a, moreB) 
     case firstB :: moreB if (firstB == firstA) => m(moreA, moreB) 
     case _ => throw new Exception("Got here: a: " + a + " b: " + b) 
     } 
    } 
    } 
} 

, 나는 다음과 같은 출력을 얻을 :

OK! List(2, 3, 4, 7) 
OK! List(2, 3, 4, 7) 
OK! List(2, 3, 4, 7) 
m(Vector(1, 2, 3, 4, 7), Vector(1, 4, 6, 9)) failed with scala.MatchError: Vector(1, 2, 3, 4, 7) (of class scala.collection.immutable.Vector) 
m(Vector(1, 2, 3, 4, 7), Vector(1, 4, 6, 9)) failed with scala.MatchError: Vector(1, 2, 3, 4, 7) (of class scala.collection.immutable.Vector) 

그것은 목록-Y 것들을 잘 실행하지만, 벡터 y를 가지 실패합니다. 내가 놓친 게 있니? 이것은 컴파일러 버그입니까? 당신은 List 이외의 아무것도 ::을 사용할 수 없습니다

@scala.annotation.tailrec def m(a: Seq, b: Seq): Seq = { 
    <synthetic> val _$this: object vectorMatch = vectorMatch.this; 
    _m(_$this,a,b){ 
    <synthetic> val temp6: Seq = a; 
    if (immutable.this.Nil.==(temp6)) 
     { 
     b 
     } 
    else 
     if (temp6.$isInstanceOf[scala.collection.immutable.::]()) 
     { 
      <synthetic> val temp8: scala.collection.immutable.:: = temp6.$asInstanceOf[scala.collection.immutable.::](); 
      <synthetic> val temp9: Long = scala.Long.unbox(temp8.hd$1()); 
      <synthetic> val temp10: List = temp8.tl$1(); 
      val firstA$1: Long = temp9; 
      val moreA: List = temp10; 
      { 
      <synthetic> val temp1: Seq = b; 
      if (immutable.this.Nil.==(temp1)) 
       { 
       a 
       } 
      else 
       if (temp1.$isInstanceOf[scala.collection.immutable.::]()) 
       { 
        <synthetic> val temp3: scala.collection.immutable.:: = temp1.$asInstanceOf[scala.collection.immutable.::](); 
        <synthetic> val temp4: Long = scala.Long.unbox(temp3.hd$1()); 
        <synthetic> val temp5: List = temp3.tl$1(); 
        val firstB: Long = temp4; 
        if (vectorMatch.this.gd1$1(firstB, firstA$1)) 
        body%11(firstB){ 
         _m(vectorMatch.this, moreA, b) 
        } 
        else 
        { 
         val firstB: Long = temp4; 
         val moreB: List = temp5; 
         if (vectorMatch.this.gd2$1(firstB, moreB, firstA$1)) 
         body%21(firstB,moreB){ 
          _m(vectorMatch.this, a, moreB) 
         } 
         else 
         { 
          val firstB: Long = temp4; 
          val moreB: List = temp5; 
          if (vectorMatch.this.gd3$1(firstB, moreB, firstA$1)) 
          body%31(firstB,moreB){ 
           _m(vectorMatch.this, moreA, moreB) 
          } 
          else 
          { 
           body%41(){ 
           throw new java.lang.Exception("Got here: a: ".+(a).+(" b: ").+(b)) 
           } 
          } 
         } 
        } 
       } 
       else 
       { 
        body%41() 
       } 
      } 

     } 
     else 
     throw new MatchError(temp6) 
    } 
}; 

답변

14

: 같은

mscalac -print 출력이 보인다. ::List을 확장하는 사례 클래스이므로 Vector이 일치하지 않으므로 unapply 메서드는 Vector에 대해 작동하지 않습니다.

object +: { 
    def unapply[T](s: Seq[T]) = 
    s.headOption.map(head => (head, s.tail)) 
} 

그래서 당신이 할 수 있습니다 :

val a :: b = List(1,2,3) // fine 
val a :: b = Vector(1,2,3) // error 

하지만 당신은 모든 시퀀스 작동 자신의 추출기를 정의 할 수있는 답변을

val a +: b = List(1,2,3) // fine 
val a +: b = Vector(1,2,3) // fine 
+0

감사합니다. –

+0

고마워요, @ dhg. 이 답변을 한 번 읽은 다음이 내용 (http://www.scala-lang.org/old/node/112)을 읽고 게시물을 다시 읽습니다. –

+0

이미 지적한 것처럼 (https://stackoverflow.com/a/11503173/1421535) 다음과 같이'Seq'를 사용할 수도 있습니다 :'case Seq (a, b, rest @ _ *)'. – acidghost

관련 문제