我尝试实现以下内容,其中a
和b
都属于Option[List[Int]]
类型:
val a = List(1, 2, 3).some
val b = for {
xs <- a
el <- xs
} yield el + 1
当然,这不起作用,因为它已被翻译成
val b = a flatMap (xs => xs map (el => el + 1))
而我正在寻找
val b = a map (xs => xs map (el => el + 1))
为了理解这一点,我必须将它们嵌套:
val b = for {
xs <- a
} yield for {
el <- xs
} yield el + 1
这最后一种形式有效。有没有办法使用第一种形式获得相同的结果?我觉得我已经使用Kleisli作曲或monad变形金刚看过这些内容,但似乎无法找到我需要的东西。
答案 0 :(得分:5)
Scalaz中的ListT
monad变换器实际上比第一个版本好一点(或者至少更简洁 - 你只需要担心一个层):
import scalaz._, Scalaz._
val a = ListT(List(1, 2, 3).some)
val b = for { el <- a } yield el + 1
或等效地:
val b = a.map(_ + 1)
此处a
和b
都是ListT[Option, Int]
的实例。您可以使用Option[List[Int]]
underlying
scala> b.underlying
res0: Option[List[Int]] = Some(List(2, 3, 4))
您可以使用ListT
执行许多其他操作,例如从值到列表选项的序列函数等。