如何将 Seq[Reader[E, A]]) 转换为 Reader[E, Seq[A]]

How to convert a Seq[Reader[E, A]]) into a Reader[E, Seq[A]]

这是我的实际解决方案

  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 没有为 Seq 提供 Traverse 实例(尽管它为 ListVector、等等)。您可以自己编写,但我建议 not doing that.

(作为脚注,sequenceU 末尾的 U 只是帮助解决 Scala 类型推断的 hack 的一部分——请参阅我的博客 post here一些背景。)