次の自由モナド定義があるとしましょう:
sealed trait SetOpsA[A]
case class AllSetNames() extends SetOpsA[Set[String]]
case class IdsFromSet(setName: String) extends SetOpsA[Set[String]]
object SetOps {
type SetOps[A] = Free[SetOpsA, A]
def allSetNames(): SetOps[Set[String]] =
liftF[SetOpsA, Set[String]](AllSetNames())
def idsFromSet(setName: String): SetOps[Set[String]] =
liftF[SetOpsA, Set[String]](IdsFromSet(setName))
}
ここで、すべてのセット名を取得し、これらのセット名ごとに idsFromSet アクションを実行したいと思います。
私はそれを次のように説明します:
val prog = for {
allSetNames <- allSetNames()
setName <- allSetNames
ids <- idsFromSet(setName)
} yield ids
しかし、理解のためにモナドを混ぜることができないので、これは不可能です。そのため、「setName <- allSetNames」の行で、コンパイラは Set が与えられており、Free が必要であると文句を言います。
周りを見回すと、モナド変換子が適しているようです。しかし、この情報では、私が見つけたモナド変換子の例は私の例からかけ離れているか、説明が抽象的すぎてこの例に実装できないように見えるため、本当に迷っています。したがって、これに関するいくつかの助けをいただければ幸いです。
編集:私はさらに一歩進んで、これを行うことで結果を達成することができます(IDのコレクションのコレクションではなく、フラット化されたIDが必要であることにも気付きました):
val prog = for {
allSetNames <- allSetNames()
ids <- allSetNames.toList.traverseU(idsFromSet)
} yield ids.flatten