如何将 Seq[Free[Functor, A]] 翻转为 Free[Functor, Seq[A]]

How to flip Seq[Free[Functor, A]] to Free[Functor, Seq[A]]

我正在学习 scalaz Free monad。我想知道如何才能让 Seq[Free[Functor, A]] 变成 Free[Functor, Seq[A]] 类似于 Future.sequence

这是代码

  type Functor[A] = Coyoneda[Command, A]
  type Script[A]= Free[Functor, A]

  case instruction(...)

  def sequence(): Seq[Script[Instruction]] = {...}

我想知道我是否可以将结果翻转为 Script[Seq[Instruction]] 如果它可以像 Future 那样,这就是 Free 是 monad 的原因吗?

非常感谢

Free.freeMonad#sequence 将帮助您翻转 Cats 和 Scalaz 中的类型构造函数。替代方案通过隐式证据要求 monad 实例,并使用编译器注入隐式实例。

只要有 Traverse[F]Applicative[G] 个实例,就会有 F[G[A]]sequence 操作(例如 Seq[Script[Instruction]])。您确实有 Applicative[Script] 实例(ScriptMonad,所以它也是 Applicative),但是 scalaz 不提供 Traverse Seq 的实例。 (不可变 Seq 原则上是可遍历的,但作者选择不提供 Traverse[Seq] 实例,大概是因为 Seq 是抽象的,因此 scalaz 不能保证返回相同的 Seq实施。)

因此我将回答 List 而不是 Seq

import scalaz.std.list._
import scalaz.syntax.traverse._

val scripts: List[Script[A]] = ???
val script: Script[List[A]] = scripts.sequence[Script, A]