Nik*_*kov 12 monads scala scalaz
我在寻找它利用单子(和类群可能)更广泛的解决方案,实现同
if( xs.contains(None) ) None else Some(xs.flatten)
做的xs
类型Seq[Option[A]]
.
我怎么能用Scalaz做到这一点?我觉得我错过了一些明显的东西.
Tra*_*own 14
有两个monad是不够的(for M
)和绰绰有余(for N
) - 当然,这还不够 - 但如果M
有一个Traverse
实例并且N
有一个Applicative
实例,你可以使用sequence
.例如:
import scalaz._, Scalaz._
def foo[A](xs: List[Option[A]]): Option[List[A]] = xs.sequence
Run Code Online (Sandbox Code Playgroud)
这有你想要的语义.请注意,我使用的是List
代替Seq
,因为Scalaz 7不再提供必要的Traverse
实例Seq
(尽管您可以轻松编写自己的实例).
正如您所注意到的,以下内容无法编译:
List(Some(1), Some(45)).sequence
Run Code Online (Sandbox Code Playgroud)
虽然你扔None
在那里很好:
scala> List(Some(1), None, Some(45)).sequence
res0: Option[List[Int]] = None
Run Code Online (Sandbox Code Playgroud)
这是因为推断类型List(Some(1), Some(45))
将是List[Some[Int]]
,并且我们没有Applicative
实例Some
.
Scalaz提供了一种方便的some
方法,Some.apply
但它可以为您提供已经输入的内容Option
,因此您可以编写以下内容:
scala> List(some(1), some(45)).sequence
res1: Option[List[Int]] = Some(List(1, 45))
Run Code Online (Sandbox Code Playgroud)
无需额外打字.