E133: Overload In Refinement — refinement에서의 오버로드

E133: Overload In Refinement — refinement에서의 오버로드

리파인먼트 타입(refinement type)이 오버로드된 정의를 도입할 때 발생하는 에러예요.

출처: Scala 3 Reference

본문

리파인먼트 타입(구조적 타입)이 오버로드된 정의를 도입할 때 발생해요.

Scala에서 리파인먼트 타입은 기반 타입에 멤버를 추가하거나 다듬을 수 있어요. 하지만 리파인먼트는 오버로드된 메서드를 도입할 수는 없어요. 리파인먼트는 구조적 제약을 서술하기 위한 것이지, 기존 것과 충돌할 새 메서드 시그니처를 만드는 게 아니기 때문이에요. 오버로드를 추가하면 메서드 해석의 의미론이 바뀌게 되는데, 이를 리파인먼트 타입은 지원하지 않아요.

예시

trait Base:
  def foo(x: Int): Int

type Refined = Base { def foo(x: String): String }

에러

-- [E133] Declaration Error: example.scala:4:26 --------------------------------
4 |type Refined = Base { def foo(x: String): String }
  |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  |                      Refinements cannot introduce overloaded definitions
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  | The refinement `method foo` introduces an overloaded definition.
  | Refinements cannot contain overloaded definitions.
   -----------------------------------------------------------------------------

해결 방법

리파인먼트 안에서 다른 메서드 이름을 쓰면 돼요.

// Use a different method name in the refinement
trait Base:
  def foo(x: Int): Int

type Refined = Base { def bar(x: String): String }

리파인먼트 대신 두 메서드를 모두 가진 트레이트를 정의하는 방법도 있어요.

// Alternative: Define a trait with both methods instead of using refinement
trait Base:
  def foo(x: Int): Int

trait Refined extends Base:
  def foo(x: String): String