Ich versuche, eine einfache Abfrage Monad zu schreiben und habe Probleme, meine generischen Typ Anmerkungen richtig zu bekommen.Scala abgeleiteten Typ Argumente - Geben Sie Grenzen auf "Nothing"
Mein erster Versuch ging wie folgt (in beträchtlichem Ausmaß für Prägnanz vereinfacht)
case class Person(val name: String)
abstract class Schema[T]
object People extends Schema[Person]
case class Query[U <: Schema[T], T](schema: U) { <---- Type signature
def results: Seq[T] = ...
def where(f: U => Operation) = ...
}
class TypeText extends Application {
val query = Query(People) <---- Type inference fails
}
Der Compiler dies nicht möchte, da es nicht die Art von ‚T‘ ableiten könnte.
error: inferred type arguments [People.type,Nothing] do not conform to method apply's type parameter bounds [U <: Schema[T],T]
Während des Experimentieren fand ich, dass Ansicht mit Grenzen statt wie erwartet funktioniert
case class Query[U <% Schema[T], T](schema: U) {
(die Verwendung von Ansicht Hinweis gebunden "<%" anstelle von Typ gebunden "<:")
In meinem begrenzten Verständnis des Typsystems, da ich eine tatsächliche Unterklasse (und nicht nur Konvertierbarkeit) von Schema [T] erwarte, würde ich annehmen, dass der Typ gebunden "<:" ist die richtige Grenze hier zu verwenden?
Wenn dies der Fall ist, was fehlt mir - wie gebe ich dem Compiler genug Hinweise, um T richtig zu schließen, wenn Sie Typgrenzen statt Ansichtsgrenzen verwenden?
Danke. Ich hatte diese Syntax gesehen und fragte mich, was das bedeutete. –
Ich glaube nicht, dass diese Antwort richtig ist. Bitte überprüfen Sie meine Antwort am Ende meiner Antwort (dieser Kommentar hätte nicht genügend Platz für die Diskussion zur Verfügung gestellt). –
@ Régis Du hast Recht. Ich habe die Scoping-Regeln in der Spezifikation falsch interpretiert. Es ist in der Tat ein Inferenzproblem, wie Sie in Ihrer Antwort beschrieben haben. Das heißt, die Verwendung eines impliziten Beweisparameters ist der einfachste Weg, die Beziehung zu codieren und die gewünschte Inferenz zu unterstützen. –