Scala 中的容器代数数据类型 [英] Container Algebraic Data Type in Scala

查看:48
本文介绍了Scala 中的容器代数数据类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对 Scala 的类型系统不是很熟悉,但这就是我想要做的.

Not very familiar with Scala's type system, but here's what I'm trying to do.

我有一个函数尝试按名字和姓氏过滤人,如果失败则仅按名字过滤.

I have a function that tries to filter people by first and last name, and if that fails filters by first name only.

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 和代数数据类型,通知调用者使用了哪个过滤器的结果.

Right now I am returning the filtered Set along with an Algebraic Data Type informing the caller which filter's results were used.

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

然而,返回 Set + MatchResult 的元组对于调用者来说并不是一个很好的契约.我想知道如何将过滤后的结果存储在 我的 MatchResult 中.

However, returning a tuple of the Set + MatchResult doesn't present a very nice contract for the caller. I'm wondering how I can store my filtered results in my MatchResult.

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

I thought I could simply change to:

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

但是编译器告诉我,我必须实现抽象成员迭代器:Iterator[A]

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

I'm not sure if I should try to extend Set or somehow make MatchResult a case class that takes a set as a constructor argument.

推荐答案

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

One approach is to use case classes to store any matches as a member.

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 是具有抽象成员的特征 必须由任何实现类实现,这就是您收到该错误的原因.

In Scala, Set is is trait that has abstract members that must be implemented by any implementing class, and that's why you are receiving that error.

在您的实现中,您可以通过以下方式使用这些类

In your implementation, you could use these classes by,

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

这篇关于Scala 中的容器代数数据类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆