2010-08-25 22 views
78

मुझे पता है कि यह प्रश्न विभिन्न तरीकों से कई बार आया है। लेकिन यह अभी भी मुझे स्पष्ट नहीं है। निम्नलिखित प्राप्त करने का कोई तरीका है।स्कैला टुपल अनपॅकिंग

def foo(a:Int, b:Int) = {} 

foo(a,b) //right way to invoke foo 

foo(getParams) // is there a way to get this working without explicitly unpacking the tuple?? 

def getParams = { 
    //Some calculations 
    (a,b) //where a & b are Int 
} 
+11

क्या होगा यदि foo कुछ वर्ग के निर्माता बनता है? – scout

+0

संभावित डुप्लिकेट [एक टुपल पर फ़ंक्शन कैसे लागू करें?] (Http://stackoverflow.com/questions/1987820/how-to-apply-a-function-to-a-tuple) – Suma

उत्तर

95

यह दो चरण की प्रक्रिया है। सबसे पहले फ़ंक्शन में फ़ू को चालू करें, फिर इसे टुपल का फ़ंक्शन बनाने के लिए उस पर tupled कॉल करें।

(foo _).tupled(getParams) 
+3

क्या यह क्लीनर नहीं होगा अगर स्कैला ने बस टुपल्स के साथ शुरू करने के लिए तर्कों के बारे में सोचा था? –

+11

हां, यह बहुत साफ होगा यदि स्कैला इसे टुपल्स और तर्क सूचियों के संचालन को एकीकृत करेगा। जो मैंने सुना है, उससे बहुत सारे गैर-स्पष्ट किनारे-मामले हैं जिन्हें ऐसा करने के लिए सावधानी से निपटने की आवश्यकता होगी। जहां तक ​​मुझे पता है, इस समय स्काला रोडमैप पर टुपल्स और तर्क सूचियों का एकीकरण नहीं है। –

+2

बस जोड़ने के लिए, अगर foo साथी ऑब्जेक्ट का फ़ैक्टरी तरीका है, तो कोई भी (Foo.apply _) का उपयोग कर सकता है। Tupled (getParams) – RAbraham

17

Function.tupled(foo _)(getParams) या डेव द्वारा सुझाए गए एक।

संपादित करें:

अपनी टिप्पणी का जवाब करने के लिए:

क्या होगा अगर foo कुछ वर्ग के निर्माता होने के लिए होता है?

उस मामले में, यह चाल काम नहीं करेगी।

आप अपनी कक्षा के साथी ऑब्जेक्ट में एक फैक्ट्री विधि लिख सकते हैं और फिर उपर्युक्त तकनीकों में से किसी एक का उपयोग करके apply विधि के tupled संस्करण प्राप्त कर सकते हैं।

scala> class Person(firstName: String, lastName: String) { 
    | override def toString = firstName + " " + lastName 
    | } 
defined class Person 

scala> object Person { 
    | def apply(firstName: String, lastName: String) = new Person(firstName, lastName) 
    | } 
defined module Person 

scala> (Person.apply _).tupled(("Rahul", "G")) 
res17: Person = Rahul G 

case class तों के साथ आप मुक्त करने के लिए एक apply विधि के साथ एक साथी वस्तु मिलता है, और इस प्रकार इस तकनीक अधिक case class तों के साथ उपयोग करने के लिए सुविधाजनक है।

scala> case class Person(firstName: String, lastName: String) 
defined class Person 

scala> Person.tupled(("Rahul", "G")) 
res18: Person = Person(Rahul,G) 

मुझे पता है कि बहुत सारे कोड डुप्लिकेशन हैं लेकिन हां ... हमारे पास मैक्रोज़ नहीं हैं (अभी तक)! ;)

+3

आखिरी उदाहरण में, आप थोड़ा सा दाढ़ी दे सकते हैं ... मामले के लिए कंपैनियन ऑब्जेक्ट्स कक्षाएं हमेशा उपयुक्त फंक्शन एन विशेषता का विस्तार करती हैं। तो अंतिम पंक्ति 'व्यक्ति.tupled ((" राहुल "," जी "))' ' हाथ से लिखित साथी वस्तुओं में भी ऐसा करना आसान है। –

+0

@ डेविड: संपादित, धन्यवाद। :-) – missingfaktor

48

@ डेव-ग्रिफिथ मर चुका है।

तुम भी कॉल कर सकते हैं:

Function.tupled(foo _) 

आप "जिस तरह से अधिक जानकारी की तुलना में मैं के लिए पूछा," क्षेत्र में घूमना चाहते हैं, वहाँ भी कर रहे हैं currying के लिए आंशिक रूप से लागू किया कार्य (और Function पर) में बनाया गया तरीकों। कुछ इनपुट/आउटपुट उदाहरण:

scala> def foo(x: Int, y: Double) = x * y 
foo: (x: Int,y: Double)Double 

scala> foo _ 
res0: (Int, Double) => Double = <function2> 

scala> foo _ tupled 
res1: ((Int, Double)) => Double = <function1> 

scala> foo _ curried 
res2: (Int) => (Double) => Double = <function1> 

scala> Function.tupled(foo _) 
res3: ((Int, Double)) => Double = <function1> 

// Function.curried is deprecated 
scala> Function.curried(foo _) 
warning: there were deprecation warnings; re-run with -deprecation for details 
res6: (Int) => (Double) => Double = <function1> 

जिसमें curried संस्करण कई तर्क सूची के साथ शुरू हो जाती है:

scala> val c = foo _ curried 
c: (Int) => (Double) => Double = <function1> 

scala> c(5) 
res13: (Double) => Double = <function1> 

scala> c(5)(10) 
res14: Double = 50.0 

अंत में, आप भी uncurry/untuple की जरूरत कर सकते हैं। Function इस के लिए builtins है:

scala> val f = foo _ tupled 
f: ((Int, Double)) => Double = <function1> 

scala> val c = foo _ curried 
c: (Int) => (Double) => Double = <function1> 

scala> Function.uncurried(c) 
res9: (Int, Double) => Double = <function2> 

scala> Function.untupled(f) 
res12: (Int, Double) => Double = <function2> 

1

अब, आप foo को लागू करने और यह इतना तरह Tuple2 वर्ग के एक परम ले कर सकते हैं।

def foo(t: Tuple2[Int, Int]) = { 
    println("Hello " + t._1 + t._2) 
    "Makes no sense but ok!" 
} 

def getParams = { 
    //Some calculations 
    val a = 1; 
    val b = 2; 
    (a, b) //where a & b are Int 
} 

// So you can do this! 
foo(getParams) 
// With that said, you can also do this! 
foo(1, 3) 
2

मैं अन्य उत्तर जो आप के लिए क्या पूछा के करीब थे में से कुछ की सराहना करते हैं, लेकिन मैं इसे एक और समारोह जो विभाजन मापदंडों में टपल मापदंडों धर्मान्तरित जोड़ने के लिए एक मौजूदा परियोजना के लिए आसान पाया:

def originalFunc(a: A, b: B): C = ... 
def wrapperFunc(ab: (A, B)): C = (originalFunc _).tupled(ab) 
संबंधित मुद्दे