这是我的实际解决方案
private def transpose[E, A](readers : Seq[Reader[E, A]]) : Reader[E, Seq[A]] =
Reader { e: E => readers.map { r => r(e) } }
scalaz是否有更简单的解决方案(可能使用现有的组合器)?
答案 0 :(得分:5)
此操作基本上是sequence
:
import scalaz.Reader, scalaz.std.list._, scalaz.syntax.traverse._
def transpose[E, A](readers: List[Reader[E, A]]): Reader[E, List[A]] =
readers.sequenceU
一般情况下,如果M
有一个Traverse
个实例且N
是一个monad,您可以通过这种方式将M[N[A]]
转换为N[M[A]]
(请参阅我的回答here了解一些其他细节。)
请注意,sequence
不适用于Seq
,因为Scalaz没有为Traverse
提供Seq
个实例(尽管它适用于List
,Vector
等)。你可以写自己的,但我建议not doing that。
(作为脚注,U
末尾的sequenceU
只是帮助Scala类型推断的黑客攻击的一部分 - 请参阅我的博文here了解某些背景信息。 )