12

感谢 Martin Odersky 在 Coursera 上提供的最新产品,我已经开始使用scala.util.Try. 然而,我惊讶地发现它不一定能很好地与集合 monad 配合使用,因为它没有实现scala.collection.GetTraversableOnce.

这可能会派上用场。例如,您可以将字符串列表转换为整数,同时丢弃错误的字符串,如下所示:

def ints(strs:List[String]):List[Int] = strs.flatMap(s => Try(s.toInt))

解决方法很简单。只需将 转换Try为 anOption并让其隐式转换为我们工作:

def ints(strs:List[String]):List[Int] = strs.flatMap(s => Try(s.toInt).toOption)

在我看来,Try要么实现GenTraversableOnce要么拥有自己的隐式转换。谁能解释为什么它没有?仅仅是事实实际上Try不是单子吗?

4

1 回答 1

1

这是一个 Monad,但在我看来,它真的不是你尝试使用它的方式的集合。FlatMap 不适用于在不同的monad 之间进行转换(M[A]=>M[B]是的,但不是M[A]=>N[B]甚至是M[A]=>N[A])。感觉更像是你想要的东西:

import scala.util.{Try, Success}

def ints2(strs: List[String]): List[Int] =
  strs.map { s => Try(s.toInt) }.collect { case Success(n) => n }

或者

import scala.util.{Try, Success, Failure}

def ints3(strs: List[String]): List[Int] = strs.flatMap { s =>
    Try(s.toInt) match {
        case Success(n) => List(n)
        case Failure(ex) => List.empty
    }
}

=>

scala> ints2(List("1","2","a","3"))
res8: List[Int] = List(1, 2, 3)
于 2013-12-14T22:53:13.157 回答