Jika saya punya EnumeratorT
dan yang sesuai IterateeT
saya bisa menjalankannya bersama-sama:
val en: EnumeratorT[String, Task] = EnumeratorT.enumList(List("a", "b", "c"))
val it: IterateeT[String, Task, Int] = IterateeT.length
(it &= en).run : Task[Int]
Jika enumerator monad "lebih besar" dari iteratee monad, saya dapat menggunakan up
atau, secara umum, Hoist
untuk "mengangkat" iteratee agar sesuai:
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]
Tetapi apa yang harus saya lakukan ketika iteratee monad "lebih besar" daripada enumerator monad?
val en: EnumeratorT[String, Id] = ...
val it: IterateeT[String, Task, Int] = ...
it &= ???
Tampaknya tidak ada Hoist
contoh untuk EnumeratorT
, atau metode "lift" yang jelas.
Enumerator
benar-benar hanya pembungkus di sekitar aStepT => IterateeT
, yang menunjukkan bahwa Anda harus "mundur" dari aStepT[E, BigMonad, A]
.Enumerator
itu hanya sumber yang efektif, bukan? Rasanya seperti saya harus dapat menggunakan sesuatu yang dapat memasokA
untuk memasokTask[A]
.Jawaban:
Dalam pengkodean yang biasa, seorang enumerator pada dasarnya adalah a
StepT[E, F, ?] ~> F[StepT[E, F, ?]]
. Jika Anda mencoba menulis metode umum yang mengubah tipe ini menjadiStep[E, G, ?] ~> G[Step[E, G, ?]]
suatuF ~> G
, Anda akan dengan cepat mengalami masalah: Anda harus "menurunkan" aStep[E, G, A]
keStep[E, F, A]
agar dapat menerapkan enumerator asli.Scalaz juga menyediakan enumerator alternatif yang terlihat seperti ini:
Pendekatan ini memungkinkan kita untuk menentukan enumerator yang spesifik tentang efek yang dibutuhkan, tetapi itu dapat "diangkat" untuk bekerja dengan konsumen yang membutuhkan konteks yang lebih kaya. Kami dapat memodifikasi contoh Anda untuk digunakan
EnumeratorP
(dan pendekatan transformasi alami yang lebih baru daripada urutan parsial monad lama):Kita sekarang dapat menyusun keduanya seperti ini:
EnumeratorP
adalah monadik (jikaF
yang aplikatif), danEnumeratorP
objek pendamping menyediakan beberapa fungsi untuk membantu dengan mendefinisikan enumerator yang terlihat banyak seperti yang diEnumeratorT
ini -adaempty
,perform
,enumPStream
, dll saya kira harus adaEnumeratorT
contoh yang tidak dapat diimplementasikan dengan menggunakan yangEnumeratorP
encoding, tetapi dari atas kepala saya, saya tidak yakin apa yang akan mereka terlihat seperti.sumber