感谢Martin Odersky在Coursera上的最新成果,我开始玩scala.util.Try
。但是,我很惊讶地发现它并不一定能很好地与集合monad一起使用,因为它没有实现scala.collection.GetTraversableOnce
。
这可能会派上用场。例如,您可以将字符串列表转换为整数,同时丢弃这样的错误:
def ints(strs:List[String]):List[Int] = strs.flatMap(s => Try(s.toInt))
解决方法很简单。只需将Try
转换为Option
,然后让隐式转换为我们工作:
def ints(strs:List[String]):List[Int] = strs.flatMap(s => Try(s.toInt).toOption)
我觉得Try
要么实现GenTraversableOnce
,要么有自己的隐式转换。任何人都可以解释为什么它没有?仅仅Try
实际上不是monad这个事实吗?
答案 0 :(得分:2)
这是一个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)