Scala多态函数用于过滤输入列表的任一个

时间:2012-08-08 15:51:56

标签: scala types monads either parametric-polymorphism

寻求更优雅的解决方案

我有这段代码,我只是在没有必要进行任何错误处理的测试用例中使用它。它的作用是:

  • 获取字符串的输入列表
  • 使用DSJSonmapper.parseDSResult方法解析它们
  • 过滤它们并从每个Either(Left is a Exception)
  • 中提取Right值

代码如下:

  def parseDs(ins: List[String]) = {
    def filterResults[U, T](in: List[Either[U, T]]): List[T] = {
      in.filter(y => y.isRight).map(z => z.right.get)
    }
    filterResults(ins.map(x => DSJsonMapper.parseDSResult(x)))
  }

现在,我还没有做过很多多态函数,但这很有效。不过我觉得它有点难看。有没有人有更好的建议,如何完成同样的事情。

我知道这将归结为个人偏好的情况。但欢迎提出建议。

2 个答案:

答案 0 :(得分:11)

collect就是出于这种情况:

def filterMe[U,T](in: List[Either[U,T]]): List[T] = in.collect{
  case Right(r) => r
}

事实上,它很擅长这一点你可能想跳过def而只是

ins.map(DSJsonMapper.parseDsResult).collect{ case Right(r) => r }

答案 1 :(得分:7)

雷克斯的回答可能更清楚一点,但这是一个略短的替代方案,只需一步即解析和“过滤”:

ins.flatMap(DSJsonMapper.parseDSResult(_).right.toOption)

我们在此处获取每个解析结果的right projection并将其转换为Option(如果解析失败则为None,否则为Some(whatever)。由于我们使用的是flatMap,因此结果中不会显示None,并且会从Some中提取值。