E146: 파라미터 초기화가 잘못됐어요
E146: 파라미터 초기화가 잘못됐어요 (Illegal Parameter Initialization)
한 클래스가 같은 파라미터화된 trait을 서로 다른 타입 인자로 상속하면서, trait 파라미터에 넘긴 값이 요구된 교집합 타입(intersection type)에 맞지 않을 때 발생하는 에러예요.
본문
클래스가 공통 파라미터화된 베이스 trait을 서로 다른 타입 인자로 상속하면, 그 파라미터의 타입은 요구된 모든 타입의 교집합(intersection)이 돼요. 그리고 파라미터를 초기화할 때 넘기는 값은 바로 이 교집합 타입에 맞아야 해요.
Base[+A](val value: A)처럼 trait이 생성자 파라미터 value: A를 갖고 있고, 한 클래스가 Derived[String](→ Base[String])과 Base[Int](42)를 동시에 상속한다고 해 볼게요. 컴파일러가 기대하는 value의 타입은 String & Int가 되는데, 실제로 넘긴 값이 그 교집합에 부합하지 않으면 이 에러가 나요.
Example
trait Base[+A](val value: A)
trait Derived[+B] extends Base[B]
class Example extends Derived[String] with Base[Int](42)
Error
-- [E146] Type Mismatch Error: example.scala:4:53 ------------------------------
4 |class Example extends Derived[String] with Base[Int](42)
| ^^
| illegal parameter initialization of value value.
|
| The argument passed for value value has type: (42 : Int)
| but class Example expects value value to have type: String & Int
|-----------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| I tried to show that
| (42 : Int)
| conforms to
| String & Int
| but none of the attempts shown below succeeded:
|
| ==> (42 : Int) <: String & Int
| ==> (42 : Int) <: String
| ==> Int <: String = false
|
| The tests were made under the empty constraint
-----------------------------------------------------------------------------
Solution
trait Base[+A](val value: A)
trait Derived[+B] extends Base[B]
// Provide a value that satisfies both type constraints
class Example extends Derived[Any] with Base[Any]("hello")
trait Base[+A](val value: A)
trait Derived[+B] extends Base[B]
// Or use consistent types across the inheritance hierarchy
class Example extends Derived[String] with Base[String]("hello")
더 알아보기
- 교집합 타입(intersection type)과 타입 공변성(variance)에 대한 자세한 내용은 Scala 3 Reference의 타입 시스템 문서를 참고하세요.