স্কেল টিপল আনপ্যাকিং


95

আমি জানি এই প্রশ্নটি বিভিন্ন উপায়ে বহুবার উঠে এসেছে। তবে এটি এখনও আমার কাছে পরিষ্কার নয়। নিম্নলিখিত অর্জনের জন্য কি কোনও উপায় আছে?

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 কিছু শ্রেণীর নির্মাতা হতে হবে?
স্কাউট

উত্তর:


107

এটি একটি দুই পদক্ষেপ পদ্ধতি। প্রথমে foo কে একটি ফাংশনে পরিণত করুন, তারপরে এটিকে টিপল কল করুন যাতে এটি একটি টিউপলের ফাংশন তৈরি করে।

(foo _).tupled(getParams)

4
স্কালা যদি কেবল টিপলস হিসাবে শুরু করার জন্য আর্গুমেন্টের কথা চিন্তা করে তবে এটি পরিষ্কার হবে না?
হেনরি গল্প

12
হ্যাঁ, স্কালা যদি এটিকে টিপলস এবং যুক্তি তালিকাগুলি পরিচালনা করে। আমি যা শুনেছি, সেগুলি থেকে অনেকগুলি স্পষ্টতই অপ্রত্যাশিত প্রবণতা রয়েছে যা ঘটতে সতর্কতার সাথে পরিচালনা করতে হবে। আমি যতদূর জানি, টিপলস এবং যুক্তি তালিকার একীকরণ এই মুহুর্তে স্কালাল রোডম্যাপে নেই।
ডেভ গ্রিফিথ

4
শুধু যোগ করার জন্য যদি foo বিন্যাস সহচর বস্তুর কারখানা পদ্ধতি, একটি ব্যবহার করতে পারেনি (Foo.apply: _) tupled (getParams)।
RAbraham

56

@ ডেভ-গ্রিফিথ মারা গেছে।

আপনি কল করতে পারেন:

Function.tupled(foo _)

আপনি যদি অঞ্চলটিতে "আমি চেয়েছি আরও তথ্যের জন্য" ভ্রমন করতে চান, তবে 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>

এতে কার্ড করা সংস্করণটি একাধিক আর্গুমেন্ট তালিকার সাথে যুক্ত করা হয়েছে:

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

পরিশেষে, প্রয়োজনে আপনি অনাস্থা / আনপুল করতে পারেন। Functionএর জন্য বিল্টিন রয়েছে:

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>


20

Function.tupled(foo _)(getParams)বা ডেভের পরামর্শ দেওয়া একটি।

সম্পাদনা:

আপনার মন্তব্যের প্রতিক্রিয়া জানাতে:

Foo কিছু শ্রেণীর নির্মাতা হতে হবে?

সেক্ষেত্রে এই কৌশলটি কাজ করবে না।

আপনি আপনার শ্রেণীর সহযোগী অবজেক্টে একটি কারখানা পদ্ধতি লিখতে পারেন এবং তারপরে applyউল্লিখিত কৌশলগুলির মধ্যে একটি ব্যবহার করে এর পদ্ধতির দ্বিগুণ সংস্করণটি পেতে পারেন ।

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)

আমি জানি এটি প্রচুর কোড ডুপ্লিকেশন তবে হায়রে ... আমাদের কাছে ম্যাক্রো নেই (এখনও)! ;)


4
এখানে সর্বশেষ উদাহরণে আপনি কিছুটা শেভ করতে পারেন ... কেস ক্লাসগুলির জন্য কম্বেনিয়ান অবজেক্টগুলি সর্বদা উপযুক্ত ফাংশনএন বৈশিষ্ট্য বাড়িয়ে দেয়। সুতরাং শেষ লাইনটি Person.tupled(("Rahul", "G")) হাত-লিখিত সহচর বস্তুগুলিতেও এটি করা সহজ।
ডেভিড উইনস্লো

3

আমি অন্য কিছু উত্তরগুলির প্রশংসা করি যা আপনি যা চেয়েছিলেন তার কাছাকাছি ছিল, তবে আমি বর্তমান প্রকল্পের জন্য আরও একটি ফাংশন যুক্ত করা সহজ বলে পেয়েছি যা দ্বিখণ্ডিত পরামিতিগুলিকে বিভক্ত পরামিতিগুলিতে রূপান্তর করে:

def originalFunc(a: A, b: B): C = ...
def wrapperFunc(ab: (A, B)): C = (originalFunc _).tupled(ab)

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)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.