Quais regras especiais o compilador scala possui para o tipo de unidade no sistema de tipos

oUnit recebe tratamento especial pelo compilador ao gerar código de bytes, porque é análogo avoid na jvm. Mas conceitualmente como um tipo no sistema de tipos scala, parece que também recebe tratamento especial na própria linguagem (exemplos abaixo).

Portanto, minha pergunta é esclarecer isso e entender quais mecanismos são usados e se realmente existe um tratamento especial para o problema.Unit tipo.

Exemplo 1:

Para tipos de escala normais, comoSeq, se um método retornarSeq, então você deve retornarSeq (ou um tipo mais específico que se estendeSeq)

def foo1: Seq[Int] = List(1, 2, 3)
def foo2: Seq[Int] = Vector(1, 2, 3)
def foo3: Seq[Int] = "foo" // Fails

Os dois primeiros exemplos são compilados porqueList[Int] eVector[Int] são subtipos deSeq[Int]. O terceiro falha porqueString não é.

Mas se eu mudar o terceiro exemplo para retornarUnit emboravai compilar e executar sem problemas, emboraString não é um subtipo deUnit:

def foo3(): Unit = "foo" // Compiles (with a warning)

Não conheço nenhum outro tipo pelo qual essa exceção seria permitida em scala. O compilador também possui regras especiais para oUnit tipo no nível do sistema de tipos ou existe algum tipo de mecanismo mais geral em funcionamento, por exemplo uma conversão implícita.

Exemplo 2:

Também não estou claro como a unidade interage em situações em que as regras de variação normalmente seriam aplicadas.

Por exemplo, às vezes atingimos esse bug comFuture[Unit] onde usamos acidentalmentemap ao invés deflatMap e crie umFuture[Future]:

def save(customer: Customer): Future[Unit] = ... // Save to database

def foo: Future[Unit] = save(customer1).map(_ => save(customer2))

omap está criando umFuture[Future[Unit]] e o compilador requer umFuture[Unit]. No entanto, isso compila!

No começo eu pensei que era porqueFuture[+T] é covariante, mas na verdadeFuture[Unit] não é um subtipo deUnit então não parece ser isso.

Se o tipo for alterado paraBoolean por exemplo, o compilador detecta o erro:

def save(customer: Customer): Future[Boolean] = ...

def foo: Future[Boolean] = save(customer1).map(_ => save(customer2)) // Compiler fails this

E para todos os outrosUnit digite que não será compilado (excetoAny PorqueFuture[Any] passa a ser um subtipo deAny por coincidência).

Então, o compilador tem regras especiais nesse caso? Ou há um processo mais geral acontecendo?

questionAnswers(3)

yourAnswerToTheQuestion