স্কালায় ভাঁজ এবং হ্রাস-বাম মধ্যে পার্থক্য


196

আমি foldLeftএবং এর মধ্যে প্রাথমিক পার্থক্য শিখেছিreduceLeft

foldLeft:

  • প্রাথমিক মান পাস করতে হবে

reduceLeft:

  • সংগ্রহের প্রথম উপাদানটিকে প্রাথমিক মান হিসাবে গ্রহণ করে
  • সংগ্রহটি ফাঁকা থাকলে ব্যতিক্রম ছুঁড়ে

অন্য কোন পার্থক্য আছে?

একই কার্যকারিতা সহ দুটি পদ্ধতি থাকার কোনও নির্দিষ্ট কারণ?


সুপারিশ আপনি দেখতে stackoverflow.com/questions/25158780/...
samthebest

আপনি যদি "স্কালায় ভাঁজ এবং হ্রাসের মধ্যে পার্থক্য" হতে প্রশ্নটি সম্পাদনা করেন তবে দুর্দান্ত হবে।
পেদ্রাম বাশিরি

উত্তর:


302

আসল উত্তর দেওয়ার আগে এখানে কয়েকটি বিষয় উল্লেখ করতে হবে:

  • আপনার প্রশ্নের সাথে কিছু করার নেই left, এটি হ্রাস এবং ভাঁজ মধ্যে পার্থক্য সম্পর্কে
  • পার্থক্যটি মোটেও বাস্তবায়ন নয়, কেবল স্বাক্ষরগুলি দেখুন।
  • বিশেষত স্কালার সাথে প্রশ্নের কিছু করার নেই, এটি কার্যকরী প্রোগ্রামিংয়ের দুটি ধারণা সম্পর্কে con

আপনার প্রশ্নে ফিরে:

এখানে স্বাক্ষরটি foldLeft( foldRightআমি যে পয়েন্টটি করতে যাচ্ছি তার জন্যও এটি হতে পারে):

def foldLeft [B] (z: B)(f: (B, A) => B): B

এবং এখানে স্বাক্ষর reduceLeft(আবার দিকটি এখানে গুরুত্বপূর্ণ নয়)

def reduceLeft [B >: A] (f: (B, A) => B): B

এই দুটি দেখতে খুব অনুরূপ এবং এই কারণেই বিভ্রান্তির সৃষ্টি হয়েছিল। reduceLeftএটির একটি বিশেষ কেস foldLeft(যার অর্থ এই যে আপনি মাঝে মাঝে উভয়টি ব্যবহার করে একই জিনিসটি প্রকাশ করতে পারেন)।

আপনি কল যখন reduceLeftএকটি বলার List[Int]এটা আক্ষরিক একটি একক মান, যা ধরনের হতে যাচ্ছে মধ্যে পূর্ণসংখ্যার পুরো তালিকা কমবে Int(অথবা একটি supertype Int, অত [B >: A])।

আপনি কল যখন foldLeftএকটি বলার List[Int]এটা (এক টুকরা কাগজ ঘূর্ণায়মান কল্পনা) পুরো তালিকা ভাঁজ হবে একটি একক মান মধ্যে, কিন্তু এই মানটি এর সাথে সম্পর্কিত করা হবে তা নয় Int(অত: পর [B])।

এখানে একটি উদাহরণ:

def listWithSum(numbers: List[Int]) = numbers.foldLeft((List.empty[Int], 0)) {
   (resultingTuple, currentInteger) =>
      (currentInteger :: resultingTuple._1, currentInteger + resultingTuple._2)
}

এই পদ্ধতিটি একটি নেয় List[Int]এবং একটি Tuple2[List[Int], Int]বা প্রদান করে (List[Int], Int)। এটি যোগফল গণনা করে এবং পূর্ণসংখ্যার তালিকার সাথে একটি টিপল দেয় এবং এর যোগফল। যাইহোক তালিকাটি পিছনে ফিরে আসে, কারণ আমরা foldLeftপরিবর্তে ব্যবহার করি foldRight

আরও গভীরতার ব্যাখ্যার জন্য তাদের সমস্তকে শাসন করতে ওয়ান ভাঁজ দেখুন ।


Bএকটি সুপারটাইপ কেন আপনি ব্যাখ্যা করতে পারেন A? দেখে মনে হচ্ছে Bআসলে Aএকটি সুপার টাইপের নয়, এর একটি সাব টাইপ হওয়া উচিত। উদাহরণস্বরূপ, ধরে নিচ্ছি Banana <: Fruit <: Food, যদি আমাদের এর একটি তালিকা Fruitথাকে তবে মনে হয় এতে কিছু Bananaগুলি থাকতে পারে তবে এতে যদি কোনও থাকেFood এস থাকে তবে টাইপটি Foodসঠিক হবে? সুতরাং এই ক্ষেত্রে, যদি Bএকটি সুপারটাইপ হয় Aএবং সেখানে উভয় Bএবং Aগুলি উভয় সমন্বিত একটি তালিকা থাকে তবে তালিকাটি ধরণের হওয়া উচিত B, নয় A। আপনি এই বৈষম্য ব্যাখ্যা করতে পারেন?
socom1880

আমি আপনার প্রশ্নটি সঠিকভাবে বুঝতে পারছি কিনা তা নিশ্চিত নই। আমার 5 বছর বয়সী উত্তর কমাতে ফাংশন সম্পর্কে বলছে যে একটি হল List[Banana]একটি একক কমে যাবে Bananaবা একটি একক Fruitবা একক Food। কারণ Fruit :> Bananaএবং `খাদ্য:> কলা।
অগাইলস্টিল

হ্যাঁ ... এটি আসলে আপনাকে ধন্যবাদ জানাতে পারে না। আমি মূলত এটি "ধরণের তালিকায় Bananaএকটি থাকতে পারে " হিসাবে ব্যাখ্যা দিচ্ছিলাম Fruit, যা বোঝায় না। আপনার ব্যাখ্যাটি কোনও অর্থবোধ করে না - fফাংশনটি পাস করার reduce()ফলে একটি Fruitবা a এর পরিণতি হতে পারে Food, যার অর্থ Bস্বাক্ষরে একটি সুপারক্লাস হওয়া উচিত, সাবক্লাস নয়।
socom1880

193

reduceLeftকেবল একটি সুবিধা পদ্ধতি। এটি সমান

list.tail.foldLeft(list.head)(_)

11
ভাল, সংক্ষিপ্ত উত্তর :) reducelftযদিও এর বানানটি সংশোধন করতে পারে
Hanxue

10
ভাল উত্তর. এটি foldখালি তালিকায় কেন কাজ reduceকরে না তা হাইলাইট করে।
মনসুর সিদ্দিকী

44

foldLeft আরও জেনেরিক, আপনি এটির মধ্যে মূলত যা রেখেছেন তার চেয়ে সম্পূর্ণ আলাদা কিছু তৈরি করতে এটি ব্যবহার করতে পারেন as reduceLeft কেবল একই ধরণের বা সংগ্রহের ধরণের সুপার টাইপের শেষ ফলাফল তৈরি করতে পারে। উদাহরণ স্বরূপ:

List(1,3,5).foldLeft(0) { _ + _ }
List(1,3,5).foldLeft(List[String]()) { (a, b) => b.toString :: a }

foldLeftগত গুটান ফলাফল নিয়ে অবসান (প্রথম সময় প্রাথমিক মান ব্যবহার করে) এবং পরবর্তী মান প্রয়োগ করা হবে।

reduceLeftঅন্যদিকে তালিকা থেকে প্রথমে দুটি মান একত্রিত করা হবে এবং সেগুলি বন্ধের ক্ষেত্রে প্রয়োগ করা হবে। পরবর্তী এটি संचयी ফলাফলের সাথে বাকী মানগুলি একত্রিত করবে। দেখা:

List(1,3,5).reduceLeft { (a, b) => println("a " + a + ", b " + b); a + b }

তালিকাটি খালি থাকলে foldLeftআইনি ফলাফল হিসাবে প্রাথমিক মান উপস্থাপন করতে পারে। reduceLeftঅন্যদিকে এটি যদি লিস্টে কমপক্ষে একটি মান খুঁজে না পায় তবে আইনগত মান থাকে না।


5

তারা উভয় স্কালার স্ট্যান্ডার্ড লাইব্রেরিতে থাকার মূল কারণ সম্ভবত এটি উভয়ই হাস্কেল স্ট্যান্ডার্ড লাইব্রেরিতে রয়েছে (বলা হয় foldlএবং foldl1)। যদি reduceLeftতা না হয় তবে এটি প্রায়শই বিভিন্ন প্রকল্পে সুবিধা পদ্ধতি হিসাবে সংজ্ঞায়িত হত।


5

রেফারেন্সের জন্য, reduceLeftনিম্নলিখিত ত্রুটি সহ একটি খালি ধারকটিতে প্রয়োগ করা হলে ত্রুটি হবে।

java.lang.UnsupportedOperationException: empty.reduceLeft

কোডটি ব্যবহার করার জন্য পুনরায় কাজ করা হচ্ছে

myList foldLeft(List[String]()) {(a,b) => a+b}

একটি সম্ভাব্য বিকল্প। অন্যটি হ'ল reduceLeftOptionবৈকল্পিকটি ব্যবহার করা যা একটি বিকল্পের মোড়ক দেওয়া ফলাফল দেয়।

myList reduceLeftOption {(a,b) => a+b} match {
  case None    => // handle no result as necessary
  case Some(v) => println(v)
}

2

স্কালায় কার্যকরী প্রোগ্রামিং নীতিগুলি থেকে (মার্টিন ওডারস্কি):

ফাংশনটি reduceLeftআরও সাধারণ ক্রিয়াকলাপের নিরিখে সংজ্ঞায়িত করা হয় foldLeft,।

foldLeftএটির মতো reduceLeftতবে অতিরিক্ত পরিমাপক হিসাবে একটি সংযোজক নেয় z, যা foldLeftখালি তালিকায় ডাকলে ফিরে আসে :

(List (x1, ..., xn) foldLeft z)(op) = (...(z op x1) op ...) op x

[এর বিপরীতে reduceLeft, যা খালি তালিকায় ডাকলে ব্যতিক্রম ছুঁড়ে ফেলে।]

কোর্স (বক্তৃতা 5.5 দেখুন) এই ফাংশনগুলির বিমূর্ত সংজ্ঞা প্রদান করে, যা তাদের পার্থক্যগুলিকে চিত্রিত করে, যদিও তারা প্যাটার্ন মেলানো এবং পুনরাবৃত্তির ক্ষেত্রে তাদের ক্ষেত্রে একই রকম।

abstract class List[T] { ...
  def reduceLeft(op: (T,T)=>T) : T = this match{
    case Nil     => throw new Error("Nil.reduceLeft")
    case x :: xs => (xs foldLeft x)(op)
  }
  def foldLeft[U](z: U)(op: (U,T)=>U): U = this match{
    case Nil     => z
    case x :: xs => (xs foldLeft op(z, x))(op)
  }
}

নোট করুন যে foldLeftপ্রকারের মান প্রদান করে U, যা অগত্যা একই ধরণের List[T]নয়, তবে কমানো লেফট তালিকার মতো একই ধরণের মান প্রদান করে)।


0

ভাঁজ / হ্রাস সহ আপনি কী করছেন তা সত্যি বুঝতে, এটি পরীক্ষা করে দেখুন: http://wiki.tcl.tk/17983 খুব ভাল ব্যাখ্যা। আপনি ভাঁজ ধারণাটি পেয়ে গেলে, হ্রাসটি উপরের উত্তরের সাথে একত্রিত হবে: list.tail.foldLeft (list.head) (_)

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