[scala] Scala의 불변 집합이 유형에서 공변이 아닌 이유는 무엇입니까?

편집 : 원래 답변을 기반 으로이 질문을 다시 작성

scala.collection.immutable.Set클래스의 형식 매개 변수의 공변되지 않습니다. 왜 이런거야?

import scala.collection.immutable._

def foo(s: Set[CharSequence]): Unit = {
    println(s)
}

def bar(): Unit = {
   val s: Set[String] = Set("Hello", "World");
   foo(s); //DOES NOT COMPILE, regardless of whether type is declared 
           //explicitly in the val s declaration
}



답변

Set함수로서의 집합 뒤에있는 개념 때문에 유형 매개 변수가 변하지 않습니다. 다음 서명은 내용을 약간 명확히해야합니다.

trait Set[A] extends (A=>Boolean) {
  def apply(e: A): Boolean
}

경우 Set에 공변 있었다 Aapply방법은 유형의 매개 변수를 사용 할 수없는 것 A때문에 함수의 contravariance에. Set잠재적으로있을 수 contravariant 에서 A,하지만 당신은 이런 일을 할 때이 역시 문제가 발생 :

def elements: Iterable[A]

요컨대, 가장 좋은 해결책은 불변 데이터 구조에 대해서도 불변을 유지하는 것입니다. immutable.Map유형 매개 변수 중 하나에서도 불변 임을 알 수 있습니다.


답변

http://www.scala-lang.org/node/9764 마틴 오더 스키 글 :

“세트 문제에 관해서는, 비 변형도 구현에서 비롯된다고 생각합니다. 공통 세트는 키 유형의 비 변형 배열 인 해시 테이블로 구현됩니다. 약간 성가신 불규칙성이라는 데 동의합니다.”

따라서 이것에 대한 원칙적인 이유를 구성하려는 우리의 모든 노력은 잘못된 것 같습니다 🙂


답변

편집 :이 답변이 주제에서 약간 벗어난 이유를 궁금해하는 사람은 질문자가 질문을 수정했기 때문입니다.

Scala의 유형 추론은 일부 상황에서 문자열이 아닌 CharSequences를 원한다는 것을 파악하기에 충분합니다. 특히 다음은 2.7.3에서 저에게 효과적입니다.

import scala.collections.immutable._
def findCharSequences(): Set[CharSequence] = Set("Hello", "World")

immutable.HashSets를 직접 만드는 방법에 관해서는 :하지 마십시오. 구현 최적화로서, 5 개 미만의 요소의 immutable.HashSets는 실제로 immutable.HashSet의 인스턴스가 아닙니다. EmptySet, Set1, Set2, Set3 또는 Set4입니다. 이러한 클래스는 immutable.Set 하위 클래스이지만 immutable.HashSet은 아닙니다.


답변