如何将 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
实例(尽管它为 List
、Vector
、等等)。您可以自己编写,但我建议 not doing that.
(作为脚注,sequenceU
末尾的 U
只是帮助解决 Scala 类型推断的 hack 的一部分——请参阅我的博客 post here一些背景。)
这是我的实际解决方案
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
实例(尽管它为 List
、Vector
、等等)。您可以自己编写,但我建议 not doing that.
(作为脚注,sequenceU
末尾的 U
只是帮助解决 Scala 类型推断的 hack 的一部分——请参阅我的博客 post here一些背景。)