Desativar seletivamente a subsunção no Scala? (digite corretamente List.contains)

List("a").contains(5)

Por que umInt nunca pode estar contido em uma lista deString, isto deve gerar um erro no tempo de compilação, mas não.

Testa desperdício e silenciosamente todos String contido na lista de igualdade para5, o que nunca pode ser verdade "5" nunca é igual a5 em Scala).

Isto foi nomeado "o problema 'contém' ". Elguns implicaram se um sistema de tipos não pode digitar corretamente essa semântica, então por que fazer um esforço extra para aplicar tipos? Por isso, considero que é um problema importante a resolver.

A parametrização do tipoB >: A doList.contains insere qualquer tipo que seja um supertipo do tipoA (o tipo dos elementos contidos na lista

trait List[+A] {
   def contains[B >: A](x: B): Boolean
}

Esta parametrização do tipo é necessária porque o+A declara que a lista é covariant no tipoA, portantoA não pode ser usado na posição contravariante, ou seja, como o tipo de um parâmetro de entrada. As listas covariantes (que devem ser imutáveis) sãomuito mais poderoso para extensão do que listas invariantes (que podem ser mutáveis

A é umString no exemplo problemático acima, masInt não é um supertipo deString, então o que aconteceu? O subsunção implícita em Scala, decidiu queAny é um supertipo mútuo de ambosString eInt.

O criador de Scala, Martin Odersky,sugerid que uma correção seria limitar o tipo de entradaB apenas àqueles tipos que possuem um método igual a queAny não tem.

trait List[+A] {
   def contains[B >: A : Eq](x: B): Boolean
}

Mas isso não resolve o problema, porque dois tipos (em que o tipo de entrada não é um supertipo do tipo dos elementos da lista) podem ter um supertipo mútuo, que é um subtipo deAny, ou seja, também um subtipo deEq. Assim, ele seria compilado sem erros e a semântica digitada incorretamente permaneceri

Desativar subsunção implícita em todos os lugaresnão uma solução ideal também, porque subsunção implícita é a razão pela qual o exemplo a seguir para subsunção aAny trabalho. E não queremos ser forçados a usar conversões de tipo quando o site de recebimento (por exemplo, passar como argumento de função) digitar corretamente a semântica para um supertipo mútuo (que pode até não serAny).

trait List[+A] {
   def ::[B >: A](x: B): List[B]
}

val x : List[Any] = List("a", 5) // see[1]

[1] List.apply chama o operador .

Então, minha pergunta é qual é a melhor solução para esse problem

Minha conclusão experimental é que a subsunção implícita deve ser desativada no site de definição em que a semântica não é digitada corretamente. Fornecerei uma resposta que mostra como desativar a subsunção implícita no site de definição do método. Existem soluções alternativas?

Observe que esse problema é geral e não isolado nas lista

ATUALIZA: Eu tenho arquivou uma solicitação de melhoria e iniciou umópico de discussão @scala neste. Também adicionei comentários nas respostas de Kim Stebel e Peter Schmitz, mostrando que suas respostas têm funcionalidade incorreta. Portanto, não há solução. Também no tópico de discussão mencionado acima, expliquei por que acho que a resposta do soc não está corret

questionAnswers(6)

yourAnswerToTheQuestion