3

Here is my actual solution

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

Is there a more straightforward solution with scalaz (maybe with an existing combinator) ?

Yann Moisan
  • 8,161
  • 8
  • 47
  • 91

1 Answers1

5

This operation is essentially 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

In general if M has a Traverse instance and N is a monad, you can transform M[N[A]] into an N[M[A]] in this way (see my answer here for some additional details).

Note that sequence won't work with Seq, since Scalaz doesn't provide a Traverse instance for Seq (although it does for List, Vector, etc.). You can write your own, but I'd suggest not doing that.

(As a footnote, the U at the end of sequenceU here is just part of a hack to help out Scala's type inference—see my blog post here for some background.)

Community
  • 1
  • 1
Travis Brown
  • 138,631
  • 12
  • 375
  • 680