Obviamente, este não foi exatamente o meu caso de uso, mas aqui está o MCVE, demonstrando o problema:
def bad = {
val in: ZLayer[Any, Any, String] = null
val layer: ZLayer[String with Int with Double, Any, Double] = null
val out: ZLayer[Any & Int, Any, Double] = in >>> layer
}
Isso deve funcionar, certo? Intellij concorda e diz que está tudo certo... até você clicar em compilar. O compilador diz:
found : zio.ZLayer[String with Int with Double,Any,Double]
required: zio.ZLayer[String with Any with Int,Any,Double]
O que??? Por que?
Curiosamente, se você alterar o primeiro Double
para a String
(ou para qualquer outra coisa, se você ajustar o out
tipo), funcionará bem:
def good = {
val in: ZLayer[Any, Any, String] = null
val layer: ZLayer[String with Int with String, Any, Double] = null
val out: ZLayer[Any & Int, Any, Double] = in >>> layer
}
Alguma ideia? Estou começando a pensar, isso é um bug do compilador?
Alguns tipos de tetris :) Vamos visualizar o que está acontecendo aqui:
Quando você compõe
in
elayer
parain >>> layer
,in
eliminaString
o que é exigido porlayer
, mas o restante (Int
eDouble
) ainda é exigido pela camada resultante. No entanto, a anotação de tipoout
no seubad
exemplo afirma que requer apenasInt
, o que não é correto.Observe que existem diferentes maneiras de corrigir o erro em
bad
:Double
ao que é exigido porout
Double
do que é exigido porlayer
Double
ao que é fornecido porin
Parece que o compilador considera o tipo de
out
correção e sugere a segunda solução, que é exatamente o que você fez nogood
.