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

时间:2015-11-30 20:44:32

标签: scala monads scalaz

这是我的实际解决方案

  private def transpose[E, A](readers : Seq[Reader[E, A]]) : Reader[E, Seq[A]] =
    Reader { e: E => readers.map { r => r(e) } }

scalaz是否有更简单的解决方案(可能使用现有的组合器)?

1 个答案:

答案 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个实例(尽管它适用于ListVector等)。你可以写自己的,但我建议not doing that

(作为脚注,U末尾的sequenceU只是帮助Scala类型推断的黑客攻击的一部分 - 请参阅我的博文here了解某些背景信息。 )