Question

EDIT : Réécrit cette question sur la base réponse originale

La classe est covariante scala.collection.immutable.Set pas dans son paramètre de type. Pourquoi est-ce?

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
}
Était-ce utile?

La solution

Set est invariant dans son paramètre de type à cause du concept de jeux comme des fonctions. Les signatures suivantes devraient clarifier les choses légèrement:

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

Si covariant étaient en A apply, la méthode serait incapable immutable.Map de prendre un paramètre de type en raison de la <=> contravariance des fonctions. Pourrait être potentiellement <=> contravariante dans <=>, mais cela provoque aussi des problèmes lorsque vous voulez faire des choses comme ceci:

def elements: Iterable[A]

En bref, la meilleure solution est de garder les choses invariante, même pour la structure de données immuables. Vous remarquerez que est également invariant <=> dans l'un de ses paramètres de type.

Autres conseils

http://www.scala-lang.org/node/9764 Martin Odersky écrit:

  

« Sur la question des ensembles, je crois que la non-variance découle également des mises en œuvre. Des ensembles communs sont mis en œuvre comme hashtables, qui sont des tableaux non variantes du type de clé. Je suis d'accord, il est une irrégularité légèrement ennuyeux. »

Alors, il semble que tous nos efforts pour construire une raison de principe pour cette malencontreuse étaient: -)

EDIT : pour ceux qui se demandent pourquoi cette réponse semble un peu hors-sujet, cela est parce que je (le questionneur) ont modifié la question.

inférence de type Scala est assez bon pour comprendre que vous voulez CharSequences et pas les chaînes dans certaines situations. En particulier, les travaux suivants pour moi en 2.7.3:

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

En ce qui concerne la façon de créer immutable.HashSets directement: ne le font pas. À titre d'optimisation de la mise en œuvre, immutable.HashSets de moins de 5 éléments ne sont pas en fait des cas de immutable.HashSet. Ils sont soit Emptyset, Set1, Set2, Set3 ou Set4. Ces classes sous-classe immutable.Set, mais pas immutable.HashSet.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top