2016-02-01 9 views
13

के लिए monads वी.एस. अनुप्रयोगी functors मान लीजिए मैं 2 दूरस्थ सेवाओं के डेटा इकट्ठा करना चाहते हैं, और जितनी जल्दी मैं प्रतिक्रिया की सेवा:वायदा

def loadUser: Future[User] 
def loadData: Future[Data] 

case class Payload(user: User, data: Data) 

मैं समझता हूँ कि यह एक कार्यान्वित async कार्य क्रमिक रूप से:

for { 
    user <- loadUser 
    data <- loadData 
} yield Payload(user,data) 

यह एक इन्हें समानांतर रूप से कार्यान्वित जबकि क्योंकि async कार्य क्रमिक रूप से चाइने होने से पहले ट्रिगर कर रहे हैं डी:

val userF = loadUser 
val dataF = loadData 
for { 
    user <- userF 
    data <- dataF 
} yield Payload(user,data) 

अंतर हालांकि मेरे लिए थोड़ा बहुत निहित है और कोई इसे पहले नोटिस नहीं कर सकता है।


Applicatives भी काम को हल करती है

(loadUser |@| loadData) { Payload(_,_) } 

कोई मुझे बता सकते हैं कि मैं नहीं बल्कि applicatives और monads के बीच का उपयोग करेंगे समानांतर async गणना प्रदर्शन करने के लिए? प्रत्येक दृष्टिकोण के पेशेवरों और विपक्ष क्या हैं?

+2

मुझे लगता है कि लगता है की जरूरत है मूल रूप से अगर आपको कुछ कॉम्प्यूटेशन ए के आउटपुट की गणना करने के लिए कुछ कॉम्प्यूटेशन ए के आउटपुट की आवश्यकता होती है तो आप एक मोनड का उपयोग करते हैं। यदि आप सिर्फ दो अलग-अलग चीजों की गणना करना चाहते हैं और उन्हें गठबंधन करना चाहते हैं, तो आवेदक करेंगे। हालांकि यह विशेष रूप से आवेदकों के बारे में 'समानांतर' नहीं है, मैं तर्क दूंगा कि ऊपर दिए गए कारणों के लिए, मोनैड मूल रूप से अनुक्रमिक हैं। वहां यदि आपको वास्तव में समानांतर गणना की आवश्यकता है, तो शायद मोनैड शायद वह संरचना नहीं है जिसे आप ढूंढ रहे हैं। * लहरें हाथ * – melps

+5

मेरा जवाब [यहां] (http://stackoverflow.com/a/19881777/334519) में कुछ प्रासंगिक चर्चा है। –

+0

समांतर में 'भविष्य' कंप्यूशन चलाने के लिए मानक मुहावरे 'ज़िप' है: '((उपयोगकर्ता, डेटा) <- loadUser ज़िप लोडडेटा) उपज पेलोड (उपयोगकर्ता, डेटा)' – Kolmar

उत्तर

12

तो, मैं अपने स्वयं के प्रश्न का उत्तर दे रहा हूं क्योंकि सभी टिप्पणियां उपयोगी संसाधनों से जुड़ी हैं।

ट्रैविस ब्राउन एक अच्छा answer था:

यह कम से कम शक्तिशाली अमूर्त कि काम किया जाएगा उपयोग करने के लिए सिर्फ एक ठोस विकास व्यवहार है। सिद्धांत रूप में यह अनुकूलन की अनुमति दे सकता है जो अन्यथा संभव नहीं होगा, लेकिन अधिक महत्वपूर्ण बात यह है कि हम कोड को अधिक पुन: प्रयोज्य लिखते हैं।

इसके अलावा वह बताते हैं एक दिलचस्प तथ्य:

यह एक शर्म की बात है कि दोनों हास्केल और स्काला वर्तमान में monads साथ इतना काम कर और अधिक सुविधाजनक (वाक्य रचना, आदि) बनाते हैं अनुप्रयोगी functors

के साथ काम करने से

Kolmar ने बताया कि यह 2 वायदा ज़िप करने संभव है:

for ((user, data) <- loadUser zip loadData) yield Payload(user, data) 

हालांकि ऐसा लगता है कि zipping more than 2 futures इतना सुरुचिपूर्ण नहीं है।

तो ऐसा लगता है कि अनुप्रयोगी functor सबसे अच्छा काम के लिए अनुकूल है, लेकिन स्काला standart पुस्तकालय हमें ज्यादा उन्हें इकाई की तुलना में उपयोग करने के लिए प्रोत्साहित नहीं करता है, और आप Scalaz या बिल्ली की तरह एक अतिरिक्त पुस्तकालय

संबंधित मुद्दे