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

标签 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 的更直接的解决方案(可能使用现有的组合器)?

最佳答案

这个操作本质上是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 类型推断的 hack 的一部分——请参阅我的博客文章 here 了解一些背景知识。)

关于scala - 如何将 Seq[Reader[E, A]]) 转换为 Reader[E, Seq[A]],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34007660/

相关文章:

scala - Scalaz 7 中 map2 的新名称是什么?

scala - IO 和 Future[Option] monad 转换器

scala - Scala 中的 "private[syntax]"

scala - 为 Spark-Shell 安装 EMR 依赖项/库

design-patterns - 有人在野外遇到过 Monad Transformer 吗?

scala - 加特林错误 : Could not find or load main class Engine

F# 自定义计算工作流程

haskell - 如果返回a = 返回b 那么a=b 吗?

list - "::(a,b)"和 "List(a,b)"模式匹配的区别

multithreading - 为什么我的斯卡拉 future 没有效率更高?