2017-12-16 3 views
1

Nicht vertraut mit Scala Typ-System, aber hier ist, was ich versuche zu tun.Container Algebraic Datentyp in Scala

Ich habe eine Funktion, die versucht, Menschen nach Vor- und Nachnamen zu filtern, und wenn das scheitert Filter nur nach dem Vornamen.

case class Person(id: Int, first: String, last:String) 
def(people: Set[Person], firstName: String, lastName: String): (MatchResult, Set[Person]) = 
    val (both, firstOnly) = people.filter(_.first == firstName).partition(_.last == lastName) 

    (both.nonEmpty, firstOnly.nonEmpty) match { 
    case (true, _) => (BothMatch, both) 
    case (false, true) => (FirstOnly, firstOnly) 
    case (_, _) => (NoMatch, Set[Person]()) 
    } 

Im Moment bin wieder ich das gefilterte Set zusammen mit einem Algebraische Datentyp informiert den Anrufer, die Ergebnisse des Filters verwendet wurden.

sealed trait MatchResult 
case object BothMatch extends MatchResult 
case object FirstOnly extends MatchResult 
case object NoMatch extends MatchResult 

jedoch Zurückgeben eines Tupels des Set + MatchResult nicht einen sehr schönen Vertrag für den Anrufer präsentieren. Ich frage mich, wie ich meine gefilterten Ergebnisse in meine MatchResult speichern kann.

Ich dachte, ich könnte einfach ändern:

sealed trait MatchResult extends Set[People] 
case object BothMatch extends MatchResult 
case object FirstOnly extends MatchResult 
case object NoMatch extends MatchResult 

Aber der Compiler sagt mir, dass ich must implement abstract member iterator: Iterator[A]

Ich bin nicht sicher, ob ich versuchen sollte Set oder irgendwie MatchResult eine case class machen zu erweitern, die nimmt eine Menge als Konstruktorargument.

Antwort

3

Ein Ansatz besteht darin, Fallklassen zum Speichern von Übereinstimmungen als Element zu verwenden.

sealed trait MatchResult 
case class BothMatch(results:Set[Person]) extends MatchResult 
case class FirstOnly(results:Set[Person]) extends MatchResult 
case object NoMatch extends MatchResult 

In Scala, Set is is trait that has abstract members, die von jeder implementierenden Klasse implementiert werden müssen, und das ist, warum Sie diesen Fehler erhalten.

in Ihrer Implementierung, Sie durch diese Klassen verwenden könnte,

(both.nonEmpty, firstOnly.nonEmpty) match { 
    case (true, _) => BothMatch(both) 
    case (false, true) => FirstOnly(firstOnly) 
    case (_, _) => NoMatch 
    } 
+0

Das ist genau das, was ich brauchte - danke! – diplosaurus