2016-11-06 4 views
6

में फ़ंक्शन को समझना प्रश्न स्कैला सिंटैक्स के बारे में सख्ती से है, हालांकि इसमें अक्का से कुछ कोड शामिल है (उदाहरण के रूप में)।स्कैला

मैं स्कैला के लिए काफी नया हूं। यहाँ पर क्या हो रहा है

def transform[C] 
(f: ExecutionContext ⇒ Materializer ⇒ Future[B] ⇒ Future[C]): Unmarshaller[A, C] = 
Unmarshaller.withMaterializer { implicit ec ⇒ implicit mat ⇒ a ⇒ f(ec)(mat)(this(a)) } 

जहां Unmarshaller.withMaterializer

def withMaterializer[A, B](f: ExecutionContext ⇒ Materializer => A ⇒ Future[B]): Unmarshaller[A, B] 

के रूप में परिभाषित: अक्का के स्रोत कोड में खुदाई मैं निम्नलिखित बहुत अजीब विधि के साथ आया था? डरावनी फ़ंक्शन f: ExecutionContext => Materializer => Future[B] => Future[C] क्या है। और मेरे लिए और अधिक अजीब लग रहा था implicit एस: implicit ec => implicit mat => a => f(ec)(mat)(this(a)) का अनुक्रम था हालांकि withMaterializer में अंतर्निहित पैरामीटर नहीं हैं।

ऐसे अनुक्रमों में अंतर्निहित अर्थ क्या है?

उत्तर

2

f: ExecutionContext => Materializer => Future[B] => Future[C] एक curried समारोह से ज्यादा कुछ नहीं है, तो आप कई पैरामीटर के साथ f(ec)(mat)(this(a)) की तरह इसे कहते सूचियां (अच्छी तरह से, तकनीकी रूप से पैरामीटर सूचियां def f(...)(...) के विपरीत एक ही फ़ंक्शन से संबंधित नहीं हैं, लेकिन वे विवरण हैं)। दूसरे शब्दों में f के रूप में लिखा जा सकता है:

f: ExecutionContext => { Materializer => { Future[B] => Future[C] } }` 

(समारोह जो एक समारोह है, जो अभी तक एक और फ़ंक्शन देता है)

अब अगर आप f(ec)(mat)(this(a)) देखो वहाँ एक फोन this(a) है, जो सिर्फ ऊपर परिभाषित किया गया है transform:

def apply(value: A)(implicit ec: ExecutionContext, materializer: Materializer): Future[B] 

(this(a) बस this.apply(a) के लिए एक कॉल है)। अब apply में दो अंतर्निहित पैरामीटर हैं, अर्थात् ec: ExecutionContext और materializer:Materializer, इसलिए इसे this(a) पर कॉल करने के लिए आपको दो निहित मूल्यों की आवश्यकता है। जो वास्तव में परिभाषा implicit ec ⇒ implicit mat ⇒ a ⇒ f(ec)(mat)(this(a)) है।यह ec और mat घोषित करता है क्योंकि सभी नेस्टेड फ़ंक्शन निकायों के लिए implicits this(a) उन्हें उठा सकते हैं। एक अन्य संभावना लिखना होगा:

ec ⇒ mat ⇒ a ⇒ f(ec)(mat)(this(a)(ec, mat)) 
0

यह करीबी और निहित पैरामीटर के साथ एक लैम्ब्डा है (जो घोषणा के दायरे में होना चाहिए)।

"डरावना" समारोह प्रकार वाक्य रचना currying है: एक तर्क जो ExecutionContext लेता है और एक तर्क यह है कि Materializer लेता है और एक अन्य फ़ंक्शन का एक और फ़ंक्शन के एक समारोह, ... आदि एक और बात implicit arguments है।

implicit val implicitInt: Int = 5 
implicit val implicitString: String = "0" 

val f: Int => String => String = { 
    implicit a => { 
    implicit b => { 
     a.toString + b 
    } 
    } 
} 

यहाँ f एक curried समारोह है कि Int लेता है और एक समारोह है कि String लेता है और String रिटर्न देता है:

यहाँ एक समान निर्माण का एक सरल उदाहरण है। फ़ंक्शन वैल्यू घोषणा के लिए सामान्य वाक्यविन्यास val f = { argument => ... } है, इसलिए यदि आप इस तर्क को निहित करते हैं, तो इसका मतलब है कि इस प्रकार का उदाहरण उस दायरे में होना चाहिए जो डिफ़ॉल्ट मान के रूप में काम करेगा। आप अभी भी कुछ तर्कों के लिए f लागू कर सकते हैं: f(1)(""), क्योंकि यह अभी भी एक फ़ंक्शन है।

आप कोड आप हर कदम के लिए नेस्टेड कार्यों को परिभाषित करते हुए के बारे में ज्यादा वरबोस रूप में दर्शा पूछ रहे हैं पुनर्लेखन सकता है:

def transform[C](f: ExecutionContext ⇒ Materializer ⇒ Future[B] ⇒ Future[C]): Unmarshaller[A, C] = { 

    def getExecutionContext(implicit ec: ExecutionContext): Materializer => (A => Future[B]) = { 

    def getMaterializer(implicit mat: Materializer): A => Future[B] = { 

     def applyF(a: A): Future[B] = f(ec)(mat)(this(a)) 
     applyF // : A => Future[B] 
    } 

    getMaterializer // : Materializer => (A => Future[B]) 
    } 

    Unmarshaller.withMaterializer(
    getExecutionContext // : ExecutionContext => (Materializer => (A => Future[B])) 
) 
} 
+0

मुझे नहीं लगता कि आप अंतर्निहित मूल्यों का उपयोग करने के लिए पैरामीटर के बिना अपने 'एफ' को कॉल कर सकते हैं। यह केवल विधियों के लिए काम करता है। फ़ंक्शन शाब्दिक अर्थ में 'अंतर्निहित' का अर्थ है कि तर्क फ़ंक्शन बॉडी के अंदर अंतर्निहित है। –

+0

आप सही हैं। 'एफ' डिफ़ॉल्ट पैरामीटर के साथ एक विधि के रूप में उपयोग करने योग्य नहीं है। मैंने बस उस सरल उदाहरण के साथ निर्माण को चित्रित करने की कोशिश की, लेकिन इसे संदर्भ से बाहर ले लिया। – laughedelic