Scalaz yineliyor: “Büyük” bir monad için “IterateeT” ile eşleşecek “Lifting” `EnumeratorT`


445

Ben EnumeratorTve karşılık gelen varsa ben IterateeTbirlikte çalıştırabilirsiniz:

val en: EnumeratorT[String, Task] = EnumeratorT.enumList(List("a", "b", "c"))
val it: IterateeT[String, Task, Int] = IterateeT.length

(it &= en).run : Task[Int]

Numaralandırıcı monad, yineleme monadından "daha büyük" ise, yinelemeyi eşleştirmek için yineleyiciyi " upveya daha genel Hoistolarak" kullanabilirim:

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]

Ancak yineleme monitörü numaralandırma monadından "büyük" olduğunda ne yapmalıyım?

val en: EnumeratorT[String, Id] = ...
val it: IterateeT[String, Task, Int] = ...

it &= ???

Bunun bir Hoistörneği EnumeratorTya da bariz bir "kaldırma" yöntemi yoktur.


59
Temiz bir soru için 1, ancak bir yana üst kapalı ben emin bu genel durumda mümkün olduğunu kafamın olduğum Enumeratorgerçekten etrafında sarıcı olduğunu StepT => IterateeTsiz "adım aşağı" gerekir önerir, a StepT[E, BigMonad, A].
Travis Brown

12
Evet, bunu doğrudan uygulamaya çalıştığımda buldum. Fakat mantıksal olarak an Enumeratorsadece etkili bir kaynaktır, değil mi? Ben sağlayabilmektedir bir şey kullanmak gerekir gibi geliyor Abeslemesine Task[A].
lmm

8
Scala hakkında bir cevap verecek kadar bilgim yok ama kendi tipinizi tanımlayıp bunun için bir kaldırma mekanizması sağlayamadınız mı?
Rob

8
Hayır, bu hiç de aynı şey değil, farklı bir tür "kaldırma".
lmm

2
@TravisBrown Eğer yazmak istiyorsanız, şu anda bu bir ödül var.
Aaron Hall

Yanıtlar:


4

Normal kodlamada bir numaralandırıcı esasen a'dır StepT[E, F, ?] ~> F[StepT[E, F, ?]]. Bu türü Step[E, G, ?] ~> G[Step[E, G, ?]]belirli bir a'ya dönüştüren genel bir yöntem yazmaya çalışırsanız F ~> G, hızlı bir şekilde bir sorunla karşılaşırsınız: orijinal numaralandırıcıyı uygulayabilmek için a'yı Step[E, G, A]bir "almanız" gerekir Step[E, F, A].

Scalaz ayrıca şöyle görünen alternatif bir numaralandırıcı kodlaması sağlar :

trait EnumeratorP[E, F[_]] {
  def apply[G[_]: Monad](f: F ~> G): EnumeratorT[E, G]
}

Bu yaklaşım, ihtiyaç duyduğu etkiler hakkında spesifik olan ancak daha zengin bağlamlar gerektiren tüketicilerle çalışmak için "kaldırılabilen" bir numaralandırıcı tanımlamamıza olanak tanır. Kullanılacak örneğinizi EnumeratorP(ve eski monad kısmi sıradan ziyade daha yeni doğal dönüşüm yaklaşımını) değiştirebiliriz:

import scalaz._, Scalaz._, iteratee._, concurrent.Task

def enum: EnumeratorP[String, Id] = ???
def iter: IterateeT[String, Task, Int] = ???

val toTask = new (Id ~> Task) { def apply[A](a: A): Task[A] = Task(a) }

Şimdi ikisini şöyle oluşturabiliriz:

scala> def result = (iter &= enum(toTask)).run
result: scalaz.concurrent.Task[Int]

EnumeratorP(eğer monadic olduğunu Fuygulamalı olan) ve EnumeratorParkadaşı nesne üzerinde olanlar çok benziyorlar enumerator'ler tanımlayan yardım için bazı işlevleri sağlar EnumeratorTçıkamaz empty, perform, enumPStreamvb Orada tahmin olmak zorunda EnumeratorTkullanılarak uygulanamamıştır örnekleri EnumeratorPkodlama, ama kafamın üst kapalı Eminim onlar nasıl görüneceğini değilim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.