Mam pewne problemy z typami w Scali, a dokładniej z błędami w czasie kompilacji, gdy nie można znaleźć egzemplarza typeclass. Załóżmy, że mam typeclass TC
i obiekt B[C]
, który ma instancję TC
tylko wtedy, gdy C
ma instancję TC
. W Scali można to zapisać: implicit def btc[C](implicit ctc: TC[C]) = new TC[B[C]] { ... }
. Gdy potrzebujesz TC[B[C]]
dla C
, dla której skalak nie może znaleźć instancji TC[C]
, skalak wyświetli błąd informujący, że nie może znaleźć TC[B[C]]
. Chociaż jest to prawdą, w komunikacie o błędzie brakuje przyczyny, dla której scalac nie może znaleźć TC[B[C]]
, to znaczy, że nie może znaleźć TC[C]
.Uczyń niejawną adnotację Scala w bardziej precyzyjny sposób
Aby zilustrować problem, postanowiłem zrobić mały przykład zabawki gdzie TC
jest PrettyPrintable
, C
jest Unit
i B
jest Option
:
import scala.annotation.implicitNotFound
@implicitNotFound("Cannot pretty print instances of the type ${T}")
trait PrettyPrintable[T] {
def prettyPrint(t: T): String
}
object PrettyPrintable {
def apply[T](implicit pp: PrettyPrintable[T]): PrettyPrintable[T] = pp
implicit def optPP[T](implicit opp: PrettyPrintable[T]) = new PrettyPrintable[Option[T]] {
override def prettyPrint(ot: Option[T]): String = ot.fold("")(opp.prettyPrint)
}
}
object Main extends App {
println(PrettyPrintable[Option[Unit]].prettyPrint(None)) // error
}
Gdybym uruchomieniu aplikacji pojawia się błąd:
[error] /home/rief/prog/scala/implicitNotFoundTest/Main.scala:24: Cannot pretty print instances of the type Option[Unit]
[error] println(PrettyPrintable[Option[Unit]].prettyPrint(None))
Jest to oczywiście prawda: scalac nie może znaleźć ładnej instancji wydruku dla typu Option[Unit]
. Problem polega na tym, że sam błąd nie jest bardzo pomocny, ponieważ nie chodzi o to, że skalak nie może znaleźć instancji klasy typów, ale więcej, dlaczego nie może jej znaleźć. W tym przypadku powodem, dla którego Option[Unit]
nie ma ładnej instancji drukowania, jest to, że Unit
nie ma ładnej instancji wydruku, ale w przypadku bardziej złożonych przypadków może to być koszmar.
Moje pytanie brzmi: czy możliwe jest popełnienie błędów niejawnych, które nie są bardziej precyzyjne?
To jest dobre. Zastanowiłem się kiedyś, jaki kontekst wyeksponować interpolatorowi na ciąg adnotacji, ale nie myślałem o niejawnej historii wyszukiwania. https://issues.scala-lang.org/browse/SI-7411 –