E211: Match Is Not Partial Function

E211: Match Is Not Partial Function

이 경고는 블록의 결과에 있는 match 표현식이 부분 함수(partial function)를 합성하는 데 사용되지 않을 때 발생해요.

출처: Scala 3 Reference

본문

함수 리터럴의 본문이 패턴 매치뿐이라면 PartialFunction이 합성될 수 있어요. 하지만 명령문 블록은 이 관용구에서 지원되지 않아요.

이 제약은 부분 함수의 평가 의미론을 단순하게 유지하기 위해 적용돼요. 그렇지 않으면 isDefinedAt이 무엇을 계산하는지 명확하지 않을 수 있어요.

예시 (Example)

def example: PartialFunction[Int, Int] = { x =>
  val y = x + 1
  y match { case n => n * 2 }
}

에러 (Error)

-- [E211] Syntax Warning: example.scala:3:4 ------------------------------------
3 |  y match { case n => n * 2 }
  |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |match expression in result of block will not be used to synthesize partial function
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  | A `PartialFunction` can be synthesized from a function literal if its body is just a pattern match.
  |
  | For example, `collect` takes a `PartialFunction`.
  |   (1 to 10).collect(i => i match { case n if n % 2 == 0 => n })
  | is equivalent to using a "pattern-matching anonymous function" directly:
  |   (1 to 10).collect { case n if n % 2 == 0 => n }
  | Compare an operation that requires a `Function1` instead:
  |   (1 to 10).map { case n if n % 2 == 0 => n case n => n + 1 }
  |
  | As a convenience, the "selector expression" of the match can be an arbitrary expression:
  |   List("1", "two", "3").collect(x => Try(x.toInt) match { case Success(i) => i })
  | In this example, `isDefinedAt` evaluates the selector expression and any guard expressions
  | in the pattern match in order to report whether an input is in the domain of the function.
  |
  | However, blocks of statements are not supported by this idiom:
  |   List("1", "two", "3").collect: x =>
  |     val maybe = Try(x.toInt) // statements preceding the match
  |     maybe match
  |     case Success(i) if i % 2 == 0 => i // throws MatchError on cases not covered
  |
  | This restriction is enforced to simplify the evaluation semantics of the partial function.
  | Otherwise, it might not be clear what is computed by `isDefinedAt`.
  |
  | Efficient operations will use `applyOrElse` to avoid computing the match twice,
  | but the `apply` body would be executed "per element" in the example.
   -----------------------------------------------------------------------------

해결 방법 (Solution)

셀렉터 표현 없이 패턴 매칭 익명 함수를 직접 사용해요.

def example: PartialFunction[Int, Int] = {
  case n => (n + 1) * 2
}

아니면 앞의 명령문 없이 파라미터에 대한 단순한 match를 사용해요.

def example: PartialFunction[Int, Int] = x => x match {
  case n => (n + 1) * 2
}