2016-12-09 7 views
0

Ich möchte eine Bibliothek in Scala implementieren. Ich fange gerade an und ich habe bereits Probleme, es in einer modularen und skalierbaren Weise zu entwerfen.Method Definition bei Verwendung von Algebraischen Datentyp in Scala

Ich brauche Hilfe! Zum Beispiel habe ich einen Baum ADT

sealed trait Tree[+A,+B,+C] 
case object EmptyTree extends Tree[Nothing, Nothing, Nothing] 
case class Leaf[A,B,C](value: C) extends Tree[A,B,C] 
case class Branch_A1[A,B,C](op: B, left: Tree[A,B,C]) extends Tree[A,B,C] 
case class Branch_A2[A,B,C](op: A, left: Tree[A,B,C], right: Tree[A,B,C]) extends Tree[A,B,C] 

Die Branch_A # definiert stellt eine Funktion mit # Argumente. Sie können sehen, wohin das geht.

Warum A, B und C? Weil die Blätter z.B. Double, und ich habe zwei Arten von Funktionen Double => Double und (Double, Double) => Double. Ich mache mir Sorgen darüber, wie sich das skalieren lässt, wenn ich die Anzahl der Zweige der Filialen vergrößere. Ich wollte das sehr flexibel machen

Ich habe zwei Fragen, eine technische, die andere in Bezug auf mein Design-Muster.

Technische Frage

Wenn ich versuche, generische Methoden zu definieren, auf solche Strukturen i Fehler erhalten arbeiten kompilieren, die ich nicht lösen kann. Zum Beispiel:

sealed trait Tree[+A,+B,+C] { 
    def evaluateTree[A,B,C] (t: Tree[A,B,C]): C = t match { 
    case Leaf(value) => value 
    case Branch_A1(op, left) => op(evaluateTree(left)) 
    case Branch_A2(op, left, right) => op(evaluateTree(left),evaluateTree(right)) 
    } 
} 
case object EmptyTree extends Tree[Nothing, Nothing, Nothing] 
case class Leaf[A,B,C](value: C) extends Tree[A,B,C] 
case class Branch_A1[A,B,C](op: B, left: Tree[A,B,C]) extends Tree[A,B,C] 
case class Branch_A2[A,B,C](op: A, left: Tree[A,B,C], right: Tree[A,B,C]) extends Tree[A,B,C] 

In op(evaluateTree(left)) i bekommen "Anwendung keine Parameter nicht unterstützt". Ich verstehe nicht warum.

Design Fragen

Wenn der Benutzer der Bibliothek ist zu dürfen, eine Domain äußern, die höher arity Funktionen dieses schwer zu verwalten. Die Anzahl der Generiktypen wird explodieren, denke ich. Wie kann ich das besser gestalten? Ich wollte das skalierbar machen. Ist die Verwendung generischer Typen am besten geeignet? Oder sollte es anders gehen? Ich habe gelesen, dass über abstrakte Datentypen sind eine Alternative

+0

'B', wie in evaluateTree Methode angegeben, ist nicht erforderlich, eine Funktion' B => C'. Können Sie versuchen, op in Branch_A1 als "B => C" zu deklarieren? Aber das würde auch nicht funktionieren, weil evaluateTree ein 'C' gibt und op ein' B' erwartet. – pedrofurla

+0

erfinden Sie Free neu? https://www.youtube.com/watch?v = 7xSfLPD6tiQ – Reactormonk

+0

Reactormonk ich kann versichern, dass ich nicht versuche, so etwas zu tun! Ich bin am Anfang der funktionalen Programmierung. Ich mache hauptsächlich Datenwissenschaft, also vermisse ich alle theoretischen Entwurfsmuster –

Antwort

0

Um die Technische Frage: der Compiler nicht genügend Informationen über A oder B wissen muss, wenn op(...) ist möglich/zulässig oder dass, wenn aufgerufen, es würde zurückkehren der richtige Typ

Was wäre, wenn (um ein einfacheres Beispiel zu verwenden) Sie case Leaf(value) => value-1 geschrieben hätten? Der Compiler wird das nicht zulassen, bis C auf eine Untergruppe von Typen definiert/eingeschränkt wurde, von denen bekannt ist, dass sie eine -(x:Int)-Methode mit einem passenden Rückgabetyp haben.

0

Am nächsten Tag schaute ich wieder auf das Problem und es ergab alles einen Sinn. Ich habe Generika viel komplizierter gemacht, als sie tatsächlich sind.

Ich hatte zuvor gesagt, dass die Generiktypen [A, B, C] zum Beispiel [(Double, Double) => Double, Double => Double, Double] bedeuten könnten. Also brauche ich nur einen parametrierten Typ:

sealed trait Tree[+A] 
case object EmptyTree extends Tree[Nothing] 
case class Leaf[A](value: A) extends Tree[A] 
case class Branch_A1[A](op: A => A, left: Tree[A]) extends Tree[A] 
case class Branch_A2[A](op: (A,A) => A, left: Tree[A], right: Tree[A]) extends Tree[A] 
Verwandte Themen