Wenn ich ein EnumeratorT
und ein entsprechendes IterateeT
habe, kann ich sie zusammen ausführen:
val en: EnumeratorT[String, Task] = EnumeratorT.enumList(List("a", "b", "c"))
val it: IterateeT[String, Task, Int] = IterateeT.length
(it &= en).run : Task[Int]
Wenn die Enumerator-Monade "größer" als die Iteratee-Monade ist, kann ich die Iteratee verwenden up
oder allgemeiner Hoist
"anheben", um sie anzupassen:
val en: EnumeratorT[String, Task] = ...
val it: IterateeT[String, Id, Int] = ...
val liftedIt = IterateeT.IterateeTMonadTrans[String].hoist(
implicitly[Task |>=| Id]).apply(it)
(liftedIt &= en).run: Task[Int]
Aber was mache ich, wenn die iterierte Monade "größer" ist als die Enumerator-Monade?
val en: EnumeratorT[String, Id] = ...
val it: IterateeT[String, Task, Int] = ...
it &= ???
Es scheint weder eine Hoist
Instanz EnumeratorT
noch eine offensichtliche "Lift" -Methode zu geben.
Enumerator
wirklich nur ein Wrapper um a istStepT => IterateeT
, was darauf hindeutet, dass Sie "zurücktreten" müssen. von aStepT[E, BigMonad, A]
.Enumerator
nur eine wirksame Quelle, oder? Es fühlt sich so an, als ob ich in der Lage sein sollte, etwas zu verwenden, das liefern kann, umA
zu liefernTask[A]
.Antworten:
In der üblichen Codierung ist ein Enumerator im Wesentlichen a
StepT[E, F, ?] ~> F[StepT[E, F, ?]]
. Wenn Sie versuchen , eine generische Methode Umwandlung dieser Art in einen schreibenStep[E, G, ?] ~> G[Step[E, G, ?]]
gegeben einF ~> G
, werden Sie schnell in ein Problem laufen: Sie müssen „senken“ ein ,Step[E, G, A]
um eineStep[E, F, A]
um in der Lage zu sein , den ursprünglichen enumerator anzuwenden.Scalaz bietet auch eine alternative Enumerator-Codierung , die folgendermaßen aussieht:
Dieser Ansatz ermöglicht es uns, einen Enumerator zu definieren, der spezifisch für die benötigten Effekte ist, der jedoch "aufgehoben" werden kann, um mit Verbrauchern zu arbeiten, die umfangreichere Kontexte benötigen. Wir können Ihr Beispiel ändern, um es zu verwenden
EnumeratorP
(und den neueren natürlichen Transformationsansatz anstelle der alten Monaden-Teilreihenfolge):Wir können die beiden nun so zusammensetzen:
EnumeratorP
monadischen ist (wenn dieF
applicative ist) und dasEnumeratorP
Begleitobjekt bietet mit der Definition Enumeratoren einige Funktionen helfen, die viel wie die , die auf aussehenEnumeratorT
-e istempty
,perform
,enumPStream
etc. Ich denke , es muss seinEnumeratorT
Instanz , die nicht umgesetzt werden könnte unter Verwendung von dieEnumeratorP
Kodierung, aber auf den ersten Blick bin ich mir nicht sicher, wie sie aussehen würden.quelle