joe*_*cii 12 monads scala implicit-conversion
感谢Martin Odersky在Coursera上的最新产品,我已经开始玩了scala.util.Try.但是,我很惊讶地发现它并不一定能很好地与集合monad一起使用,因为它没有实现scala.collection.GetTraversableOnce.
这可能会派上用场.例如,您可以将字符串列表转换为整数,同时抛弃坏的字符串,如下所示:
def ints(strs:List[String]):List[Int] = strs.flatMap(s => Try(s.toInt))
Run Code Online (Sandbox Code Playgroud)
解决方法很简单.只需将其转换Try为an Option并让其隐式转换为我们工作:
def ints(strs:List[String]):List[Int] = strs.flatMap(s => Try(s.toInt).toOption)
Run Code Online (Sandbox Code Playgroud)
在我看来,Try它将实现GenTraversableOnce或具有自己的隐式转换.谁能解释为什么不呢?事实上,这实际上Try并不是一个单子吗?
它是一个 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 }
Run Code Online (Sandbox Code Playgroud)
或者
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
}
}
Run Code Online (Sandbox Code Playgroud)
=>
scala> ints2(List("1","2","a","3"))
res8: List[Int] = List(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)