स्लैज़ इट्रेटेस: "लिफ्टिंग" `एनुमिटेरट 'को मैच के लिए' इरेटेटे '


445

अगर मेरे पास एक EnumeratorTऔर एक है तो IterateeTमैं उन्हें एक साथ चला सकता हूं:

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

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

यदि गणना करने वाले मोनाड, इट्रैटेड मोनाड की तुलना में "बड़ा" है, तो मैं मिलान के लिए इट्रिएट को "लिफ्ट" करने के लिए upया अधिक सामान्यतः उपयोग कर सकता हूं Hoist:

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]

लेकिन मैं क्या कर सकता हूं जब इट्रिमेट मोनाड एनुमरेटर मोनाड से "बड़ा" है?

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

it &= ???

वहाँ के लिए एक Hoistउदाहरण है EnumeratorT, और न ही कोई स्पष्ट "लिफ्ट" विधि प्रतीत नहीं होता है ।


59
एक साफ सवाल के लिए +1, लेकिन ऊपर से मैं अपने सिर के बारे में निश्चित नहीं हूं कि यह सामान्य मामले में संभव है, क्योंकि Enumeratorयह वास्तव में एक ए के चारों ओर सिर्फ एक आवरण है StepT => IterateeT, जो बताता है कि आपको "पद छोड़ने" की आवश्यकता होगी a से StepT[E, BigMonad, A]
ट्रैविस ब्राउन

12
हाँ, मैंने पाया कि जब मैंने इसे सीधे लागू करने की कोशिश की थी। लेकिन तार्किक रूप Enumeratorसे सिर्फ एक प्रभावी स्रोत है, है ना? ऐसा लगता है कि मुझे उस चीज़ का उपयोग करने में सक्षम होना चाहिए जो आपूर्ति Aकरने के लिए आपूर्ति कर सकती है Task[A]
लम

8
मुझे उत्तर देने के लिए स्काला के बारे में पर्याप्त जानकारी नहीं है लेकिन क्या आप अपने स्वयं के प्रकार को परिभाषित नहीं कर सकते हैं और इसके लिए एक उठाने की व्यवस्था प्रदान कर सकते हैं ?
रोब

8
नहीं, यह बिल्कुल समान बात नहीं है, यह एक अलग तरह का "लिफ्टिंग" है।
लम

2
यदि आप इसे लिखना चाहते हैं तो @TravisBrown इस समय इस पर एक इनाम है।
हारून हॉल

जवाबों:


4

सामान्य एन्कोडिंग में एक एनुमर अनिवार्य रूप से एक है StepT[E, F, ?] ~> F[StepT[E, F, ?]]। यदि आप इस प्रकार को Step[E, G, ?] ~> G[Step[E, G, ?]]दिए गए ए में परिवर्तित करने के लिए एक सामान्य विधि लिखने की कोशिश करते हैं F ~> G, तो आप जल्दी से एक समस्या में भाग लेंगे: आपको मूल गणनाकर्ता को लागू करने में सक्षम होने के Step[E, G, A]लिए ए Step[E, F, A]में "कम" करने की आवश्यकता है ।

स्कैलाज़ एक वैकल्पिक एन्यूमरेटर एन्कोडिंग भी प्रदान करता है जो इस तरह दिखता है:

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

यह दृष्टिकोण हमें एक एन्यूमरेटर को परिभाषित करने की अनुमति देता है जो इसके लिए आवश्यक प्रभावों के बारे में विशिष्ट है, लेकिन यह उन उपभोक्ताओं के साथ काम करने के लिए "उठाया" जा सकता है जिन्हें समृद्ध संदर्भों की आवश्यकता होती है। हम आपके उदाहरण का उपयोग करने के लिए संशोधित कर सकते हैं EnumeratorP(और पुराने मोनड आंशिक आदेश के बजाय नए प्राकृतिक परिवर्तन दृष्टिकोण):

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) }

हम अब इस तरह से दो रचना कर सकते हैं:

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

EnumeratorPmonadic है (यदि Fअनुप्रयोगी है), और EnumeratorPसाथी वस्तु प्रगणक उस पर लोगों की तरह एक बहुत लग रही है परिभाषित करने के साथ मदद करने के लिए कुछ कार्य प्रदान करता EnumeratorT, वहाँ के empty, perform, enumPStream, आदि मैं वहाँ लगता है कि होना जरूरी EnumeratorTउदाहरणों का उपयोग कर लागू नहीं किया जा सकता है EnumeratorPएन्कोडिंग, लेकिन मेरे सिर के ऊपर से मैं नहीं यकीन है कि वे कैसे दिखते हैं हूँ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.