这是我的实际解决方案
private def transpose[E, A](readers : Seq[Reader[E, A]]) : Reader[E, Seq[A]] =
Reader { e: E => readers.map { r => r(e) } }
是否有使用 scalaz 的更直接的解决方案(可能使用现有的组合器)?
最佳答案
这个操作本质上是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 类型推断的 hack 的一部分——请参阅我的博客文章 here 了解一些背景知识。)
关于scala - 如何将 Seq[Reader[E, A]]) 转换为 Reader[E, Seq[A]],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34007660/