Scala中的容器代数数据类型

时间:2017-12-16 00:13:00

标签: scala scala-collections algebraic-data-types

对Scala的类型系统不太熟悉,但这是我尝试做的事情。

我有一个功能,试图按名字和姓氏过滤人,如果失败只按名字过滤。

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]())
  }

现在我返回已过滤的Set以及代数数据类型,通知来电者使用过滤器的结果。

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

但是,返回Set + MatchResult的元组并不会给调用者带来非常好的合同。我想知道如何将过滤结果存储在我的MatchResult中。

我以为我可以简单地改为:

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

但编译器告诉我,must implement abstract member iterator: Iterator[A]

我不确定是否应该尝试扩展Set或以某种方式使MatchResult成为case class,将一个集合作为构造函数参数。

1 个答案:

答案 0 :(得分:3)

一种方法是使用案例类将任何匹配项存储为成员。

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

在Scala中,Set is is trait that has abstract members必须由任何实现类实现,这就是您收到该错误的原因。

在您的实现中,您可以按照

使用这些类
(both.nonEmpty, firstOnly.nonEmpty) match {
    case (true, _) => BothMatch(both)
    case (false, true) => FirstOnly(firstOnly)
    case (_, _) => NoMatch
  }