EDIT : Reescrita esta pergunta com base na resposta original
A scala.collection.immutable.Set
classe não é covariante em seu parâmetro de tipo. Por que é isso?
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
}
scala
set
covariance
scala-collections
oxbow_lakes
fonte
fonte
foo(s.toSet[CharSequence])
compila bem. OtoSet
método é O (1) - ele apenas envolveasInstanceOf
.foo(Set("Hello", "World"))
compila também no 2.10, já que Scala parece ser capaz de inferir o tipo certo de Conjunto. Porém, ele não funciona com conversões implícitas ( stackoverflow.com/questions/23274033/… ).Respostas:
Set
é invariável em seu parâmetro de tipo devido ao conceito por trás dos conjuntos como funções. As seguintes assinaturas devem esclarecer um pouco as coisas:Se
Set
fosse covariante emA
, oapply
método seria incapaz de tomar um parâmetro do tipoA
devido à contravariância de funções.Set
poderia ser potencialmente contravariant emA
, mas isso também causa problemas quando você quer fazer coisas como esta:Resumindo, a melhor solução é manter as coisas invariáveis, mesmo para a estrutura de dados imutável. Você notará que
immutable.Map
também é invariável em um de seus parâmetros de tipo.fonte
List(1,2,3).contains _
é(Any) => Boolean
, enquanto o tipo deSet(1,2,3).contains _
éres1: (Int) => Boolean
.em http://www.scala-lang.org/node/9764 Martin Odersky escreve:
Então, parece que todos os nossos esforços para construir uma razão de princípio para isso foram equivocados :-)
fonte
Seq
é covariante ... estou faltando alguma coisa?Array[Any]
internamente.EDITAR : para quem está se perguntando por que essa resposta parece um pouco fora do tópico, isso é porque eu (o questionador) modifiquei a pergunta.
A inferência de tipo do Scala é boa o suficiente para descobrir que você deseja CharSequences e não Strings em algumas situações. Em particular, o seguinte funciona para mim em 2.7.3:
Sobre como criar conjuntos.HashSets imutáveis diretamente: não. Como uma otimização de implementação, immutable.HashSets com menos de 5 elementos não são realmente instâncias de immutable.HashSet. Eles são EmptySet, Set1, Set2, Set3 ou Set4. Essas classes são subclasses de immutable.Set, mas não de immutable.HashSet.
fonte