में नि: शुल्क इकाई कुछ सप्ताह पहले Dragisa Krsmanovic पूछा a question here कैसे Scalaz 7 में मुक्त इकाई का उपयोग करने के इस स्थिति में ढेर अतिप्रवाह से बचने के लिए (मैं अपने कोड थोड़ा अनुकूल नहीं बनाया है) के बारे में:अनुप्रयोगी बनाम monadic combinators और Scalaz
import scalaz._, Scalaz._
def setS(i: Int): State[List[Int], Unit] = modify(i :: _)
val s = (1 to 100000).foldLeft(state[List[Int], Unit](())) {
case (st, i) => st.flatMap(_ => setS(i))
}
s(Nil)
मैंने सोचा था कि that just lifting a trampoline into StateT
काम करना चाहिए:
import Free.Trampoline
val s = (1 to 100000).foldLeft(state[List[Int], Unit](()).lift[Trampoline]) {
case (st, i) => st.flatMap(_ => setS(i).lift[Trampoline])
}
s(Nil).run
लेकिन यह अभी भी ढेर चल रही है, तो मैं बस एक टिप्पणी के रूप में यह पोस्ट।
Dave Stevens सिर्फ pointed out कि अनुप्रयोगी *>
monadic flatMap
वास्तव में के बजाय साथ उन्हें क्रमबद्ध बस ठीक काम करता है:
val s = (1 to 100000).foldLeft(state[List[Int], Unit](()).lift[Trampoline]) {
case (st, i) => st *> setS(i).lift[Trampoline]
}
s(Nil).run
(ठीक है, यह निश्चित रूप से सुपर धीमी है, क्योंकि वह कीमत है जो आप कुछ भी की तरह दिलचस्प करने के लिए भुगतान करते हैं है यह स्कैला में है, लेकिन कम से कम कोई स्टैक ओवरफ़्लो नहीं है।)
यहां क्या हो रहा है? मुझे नहीं लगता कि इस अंतर के लिए एक सिद्धांतबद्ध कारण हो सकता है, लेकिन वास्तव में मुझे नहीं पता कि कार्यान्वयन में क्या हो रहा है और इस समय आस-पास खोदने का समय नहीं है। लेकिन मैं उत्सुक हूं और अगर कोई और जानता है तो यह अच्छा होगा।
+1 और धन्यवाद, लेकिन मेरी समझ गया था जिस तरह से ट्रैम्पोलिन के 'flatMap' ढेर पर बाँध reifies इसका मतलब है कि हम सुरक्षित यहाँ भी होना चाहते हैं अगर हम उस परिणाम को फेंक नहीं रहे थे? –
@cdk मुझे नहीं लगता कि यह जवाब है। एक और ऑपरेटर चुनें जो बाएं * के परिणाम पर निर्भर करता है और * को 'बाइंड' के बजाय 'लागू करें' की आवश्यकता होती है। जैसे '| @ |' https://gist.github.com/drstevens/3ea464446ee59463af1e – drstevens