ফ্ল্যাটম্যাপ / মানচিত্রের রূপান্তর থেকে বোঝার জন্য বিভ্রান্ত


87

আমি সত্যিই মানচিত্র এবং ফ্ল্যাটম্যাপ বোঝে বলে মনে হচ্ছে না। আমি যা বুঝতে ব্যর্থ হচ্ছি তা হল একটি বোধগম্যতা কীভাবে মানচিত্র এবং ফ্ল্যাটম্যাপে নেস্টেড কলগুলির ক্রম। নীচের উদাহরণটি স্কালায় ফাংশনাল প্রোগ্রামিং এর

def bothMatch(pat:String,pat2:String,s:String):Option[Boolean] = for {
            f <- mkMatcher(pat)
            g <- mkMatcher(pat2)
 } yield f(s) && g(s)

অনুবাদ

def bothMatch(pat:String,pat2:String,s:String):Option[Boolean] = 
         mkMatcher(pat) flatMap (f => 
         mkMatcher(pat2) map (g => f(s) && g(s)))

MkMatcher পদ্ধতিটি নিম্নলিখিত হিসাবে সংজ্ঞায়িত করা হয়েছে:

  def mkMatcher(pat:String):Option[String => Boolean] = 
             pattern(pat) map (p => (s:String) => p.matcher(s).matches)

এবং নিদর্শন পদ্ধতিটি নিম্নরূপ:

import java.util.regex._

def pattern(s:String):Option[Pattern] = 
  try {
        Some(Pattern.compile(s))
   }catch{
       case e: PatternSyntaxException => None
   }

যদি কেউ এখানে মানচিত্র এবং ফ্ল্যাটম্যাপ ব্যবহারের পিছনে যুক্তি সম্পর্কে কিছুটা আলোকপাত করতে পারে তবে দুর্দান্ত হবে।

উত্তর:


201

টিএল; ডিআর সরাসরি চূড়ান্ত উদাহরণে যান

আমি চেষ্টা করব এবং পুনরুদ্ধার করব।

সংজ্ঞা

forধী একত্রিত করতে একটি বাক্য গঠন শর্টকাট flatMapএবং mapএকটি উপায় পড়া এবং প্রায় কারণ সহজে হবে।

আসুন জিনিসগুলি কিছুটা সহজ করুন এবং ধরে নেওয়া যাক যে classউভয়টি পূর্বোক্ত উভয় পদ্ধতি সরবরাহ করে তাকে একটি বলা যেতে পারে monadএবং আমরা প্রতীকটি একটি অভ্যন্তরের প্রকারের সাথে M[A]বোঝাতে ব্যবহার করব ।monadA

উদাহরণ

কিছু সাধারণভাবে দেখা মনদের মধ্যে রয়েছে:

  • List[String] কোথায়
    • M[X] = List[X]
    • A = String
  • Option[Int] কোথায়
    • M[X] = Option[X]
    • A = Int
  • Future[String => Boolean] কোথায়
    • M[X] = Future[X]
    • A = (String => Boolean)

মানচিত্র এবং ফ্ল্যাটম্যাপ

জেনেরিক মোনাডে সংজ্ঞায়িত M[A]

 /* applies a transformation of the monad "content" mantaining the 
  * monad "external shape"  
  * i.e. a List remains a List and an Option remains an Option 
  * but the inner type changes
  */
  def map(f: A => B): M[B] 

 /* applies a transformation of the monad "content" by composing
  * this monad with an operation resulting in another monad instance 
  * of the same type
  */
  def flatMap(f: A => M[B]): M[B]

যেমন

  val list = List("neo", "smith", "trinity")

  //converts each character of the string to its corresponding code
  val f: String => List[Int] = s => s.map(_.toInt).toList 

  list map f
  >> List(List(110, 101, 111), List(115, 109, 105, 116, 104), List(116, 114, 105, 110, 105, 116, 121))

  list flatMap f
  >> List(110, 101, 111, 115, 109, 105, 116, 104, 116, 114, 105, 110, 105, 116, 121)

প্রকাশের জন্য

  1. <-প্রতীক ব্যবহার করে এক্সপ্রেশনটির প্রতিটি লাইন একটি flatMapকলটিতে অনুবাদ করা হয় , শেষ পংক্তির পরিবর্তে একটি শেষ mapকলটিতে অনুবাদ করা হয় , যেখানে বাম-হাতের "সীমাবদ্ধ চিহ্ন" আর্গুমেন্ট ফাংশনের প্যারামিটার হিসাবে পাস হয় (কী আমরা পূর্বে ডেকেছি f: A => M[B]):

    // The following ...
    for {
      bound <- list
      out <- f(bound)
    } yield out
    
    // ... is translated by the Scala compiler as ...
    list.flatMap { bound =>
      f(bound).map { out =>
        out
      }
    }
    
    // ... which can be simplified as ...
    list.flatMap { bound =>
      f(bound)
    }
    
    // ... which is just another way of writing:
    list flatMap f
    
  2. শুধুমাত্র একটির সাথে একটি অভিব্যক্তিকে যুক্তিতে <-রূপান্তরিত অভিব্যক্তিটির সাথে একটি mapকলে রূপান্তরিত হয় :

    // The following ...
    for {
      bound <- list
    } yield f(bound)
    
    // ... is translated by the Scala compiler as ...
    list.map { bound =>
      f(bound)
    }
    
    // ... which is just another way of writing:
    list map f
    

এখন বিষয়

আপনি দেখতে পাচ্ছেন, mapঅপারেশনটি মূলটির "আকৃতি" সংরক্ষণ করে monad, তাই yieldঅভিব্যক্তির ক্ষেত্রেও একই ঘটে : Listএকটিতে Listঅপারেশনের মাধ্যমে রূপান্তরিত সামগ্রীর একটি অবশেষ yield

অন্যদিকে, প্রতিটি প্রতিবন্ধক লাইনটি forকেবল ধারাবাহিকের একটি রচনা monads, যা একটি একক "বাহ্যিক আকৃতি" বজায় রাখতে "সমতল" হওয়া আবশ্যক।

ধরুন যে এক মুহুর্তের জন্য প্রতিটি অভ্যন্তরীণ বাঁধাই একটি mapকলটিতে অনুবাদ করা হয়েছিল , তবে ডান হাত একই A => M[B]ফাংশন ছিল, আপনি M[M[B]]উপলব্ধির প্রতিটি লাইনের জন্য একটি দিয়ে শেষ করবেন ।
পুরো forসিনট্যাক্সের উদ্দেশ্যটি হ'ল ক্রমবর্ধমান মনাদিক ক্রিয়াকলাপের সমঝোতা সহজেই "সমতল" করা (অর্থাত্ "অপারেশনগুলি যে" মনাদিক আকারে "একটি মানকে" উত্তোলন করে " A => M[B]:) একটি চূড়ান্ত ক্রিয়া সংযোজন mapকরে যা সম্ভবত একটি সমাপ্তি রূপান্তর সম্পাদন করে।

আমি আশা করি এটি অনুবাদ বাছাইয়ের পিছনে যুক্তিটি ব্যাখ্যা করে, যা যান্ত্রিক উপায়ে প্রয়োগ করা হয়, এটি: n flatMapনেস্টেড কলগুলি একক mapকল দ্বারা শেষ হয় ।

একটি সঙ্কলিত উদাহরণস্বরূপ উদাহরণ সিনট্যাক্সের
বহিঃপ্রকাশ দেখানোর জন্যfor

case class Customer(value: Int)
case class Consultant(portfolio: List[Customer])
case class Branch(consultants: List[Consultant])
case class Company(branches: List[Branch])

def getCompanyValue(company: Company): Int = {

  val valuesList = for {
    branch     <- company.branches
    consultant <- branch.consultants
    customer   <- consultant.portfolio
  } yield (customer.value)

  valuesList reduce (_ + _)
}

আপনি কি টাইপ অনুমান করতে পারেন valuesList?

যেমন ইতিমধ্যে বলা হয়েছে, এর আকারটি monadবোঝার মাধ্যমে বজায় রাখা হয়, তাই আমরা একটি Listইন দিয়ে শুরু করব company.branchesএবং অবশ্যই একটি দিয়ে শেষ করব List
পরিবর্তে অভ্যন্তরীণ প্রকারটি পরিবর্তিত হয় এবং yieldপ্রকাশ দ্বারা নির্ধারিত হয় : যাcustomer.value: Int

valueList একটি হতে হবে List[Int]


4
শব্দগুলি "মেটা-ভাষার অন্তর্গত" হিসাবে একই এবং কোড ব্লক থেকে সরানো উচিত।
দিন

4
প্রতিটি এফপি শিক্ষানবিস এটি পড়া উচিত। কিভাবে এটা অর্জন করা যেতে পারে?
Mert inan

4
@ মেলস্টন এর সাথে একটি উদাহরণ তৈরি করি Lists। যদি আপনি কোনও মূল্যকে mapদ্বিগুণ করে কোনও ফাংশন A => List[B](যা একটি অত্যাবশ্যক মনডিক অপারেশনগুলির মধ্যে একটি) থাকে তবে আপনি একটি তালিকা [তালিকা [বি]] দিয়ে শেষ করেন (আমরা মেনে নিচ্ছি যে প্রকারগুলি মিলে যায়)। বোধগম্য অভ্যন্তরীণ লুপটি সংশ্লিষ্ট flatMapক্রিয়াকলাপের সাথে সেই ফাংশনগুলি রচনা করে , তালিকা [তালিকা [বি]] আকারকে একটি সাধারণ তালিকাতে [বি] আকার দেয় ... আমি আশা করি এটি স্পষ্ট
প্যাগোডা_5 বি

4
এটি আপনার উত্তর পড়া খাঁটি অসাধারণতা হয়েছে। আমি আশা করি আপনি স্কেল সম্পর্কে একটি বই লিখতে চান, আপনার একটি ব্লগ বা কিছু আছে?
টোমার বেন ডেভিড

4
@ কুলব্রিজেজ এটি হতে পারে যে আমি এটি পরিষ্কারভাবে প্রকাশ করি নি। আমি যা বোঝাতে চেয়েছি তা হ'ল yieldধারাটি, কার customer.valueপ্রকার Int, তাই সম্পূর্ণরূপে for comprehensionএকটিকে মূল্যায়ন করে List[Int]
প্যাগোডা_৫ বি

7

আমি কোনও স্কেল মেগা মন নই তাই নির্দ্বিধায় আমাকে সংশোধন করতে পারি, তবে এইভাবে আমি flatMap/map/for-comprehensionনিজের কাছে সাগাটি ব্যাখ্যা করি!

বুঝতে for comprehensionএবং এর অনুবাদ করতে scala's map / flatMapআমাদের অবশ্যই ছোট পদক্ষেপ নিতে হবে এবং রচনা অংশগুলি বুঝতে হবে - mapএবং flatMap। তবে scala's flatMapকেবল নিজেকে জিজ্ঞাসা করার mapসাথেই নয় flatten! যদি তাই হয় তবে এতগুলি বিকাশকারী কেন এটির বা এর উপলব্ধি পাওয়া এত কঠিন মনে করেন for-comprehension / flatMap / map। ঠিক আছে, আপনি যদি কেবল স্কালার mapএবং flatMapস্বাক্ষরের দিকে লক্ষ্য করেন তবে দেখবেন যে তারা একই রিটার্নের ধরনটি ফিরে আসে M[B]এবং তারা একই ইনপুট যুক্তি A(কমপক্ষে তারা যে ফাংশনটি গ্রহণ করে থাকে তার প্রথম অংশ) নিয়ে কাজ করে যদি তাই হয় তবে কোনও পার্থক্য কী?

আমাদের পরিকল্পনা

  1. স্ক্যালার বুঝুন map
  2. স্ক্যালার বুঝুন flatMap
  3. স্ক্যালার বুঝুন for comprehension.`

স্কালার মানচিত্র

স্কাল মানচিত্র স্বাক্ষর:

map[B](f: (A) => B): M[B]

কিন্তু আমরা এই স্বাক্ষরটি দেখলে একটি বড় অংশ অনুপস্থিত রয়েছে এবং এটি - এটি Aকোথা থেকে আসে? আমাদের ধারক ধরনের হয় A, যাতে তার গুরুত্বপূর্ণ ধারক প্রেক্ষাপটে এই ফাংশন তাকান - M[A]। আমাদের ধারকটি Listবিভিন্ন ধরণের আইটেম হতে পারে Aএবং আমাদের mapফাংশনটি এমন একটি ফাংশন নেয় যা প্রতিটি ধরণের আইটেমকে টাইপ Aকরে রূপান্তরিত করে B, তারপরে এটি একটি ধরণের ধারক B(বা M[B]) ফেরত দেয়

কনটেইনারটি বিবেচনা করে মানচিত্রের স্বাক্ষরটি লিখি:

M[A]: // We are in M[A] context.
    map[B](f: (A) => B): M[B] // map takes a function which knows to transform A to B and then it bundles them in M[B]

মানচিত্র সম্পর্কে একটি অত্যন্ত অত্যন্ত অত্যন্ত গুরুত্বপূর্ণ বিষয়টি নোট করুন - এটি আউটপুট ধারকটিতে স্বয়ংক্রিয়ভাবে বান্ডিল M[B]হয়ে যায় যার উপর আপনার কোনও নিয়ন্ত্রণ নেই। আসুন আমরা এটি আবার জোর দিন:

  1. mapআমাদের জন্য আউটপুট ধারক চয়ন করে এবং এটি উত্স হিসাবে আমরা যে উত্সে কাজ করি ঠিক তেমনই ধারক হয়ে উঠবে কনটেইনার জন্য M[A]আমরা Mকেবল একই পাত্রে পাই B M[B]এবং অন্য কিছুর জন্য পাই না!
  2. mapআমাদের জন্য এই আধারিকরণের আমরা শুধু থেকে একটি ম্যাপিং দিতে না Aকরার Bএবং এটি বক্স-এ তা দিয়া M[B]আমাদের জন্য বক্স-এ করা হবে!

আপনি দেখতে পাচ্ছেন যে আপনি containerizeঅভ্যন্তরীণ আইটেমগুলিকে কীভাবে রূপান্তর করতে হবে তা সুনির্দিষ্টভাবে আইটেমটিতে নির্দিষ্ট করা হয়নি । এবং যেমন আমাদের Mউভয়ের জন্য একই ধারক রয়েছে M[A]এবং এর M[B]অর্থ M[B]একই পাত্রে, অর্থাত্ যদি আপনার কাছে থাকে List[A]তবে আপনি এটির কাজটি করতে যাচ্ছেন List[B]এবং আরও গুরুত্বপূর্ণভাবে mapএটি আপনার জন্য করছে!

এখন যে আমরা মোকাবেলা করেছি mapএর দিকে এগিয়ে যাওয়া যাক flatMap

স্কালার ফ্ল্যাটম্যাপ

আসুন এর স্বাক্ষর দেখুন:

flatMap[B](f: (A) => M[B]): M[B] // we need to show it how to containerize the A into M[B]

আপনি flatMapফ্ল্যাটম্যাপে মানচিত্র থেকে বড় পার্থক্য দেখেন আমরা এটিকে এমন ফাংশন সরবরাহ করছি যা কেবলমাত্র রূপান্তর করে না A to Bতবে এতে রূপান্তর করে M[B]

কারা পাত্রে রাখে আমাদের যত্ন নেই?

সুতরাং কেন আমরা ম্যাপ / ফ্ল্যাটম্যাপে ইনপুট ফাংশনটির এত যত্ন করি না কেন ম্যাপটি কনটেইনারাইজেশন করে M[B]বা মানচিত্র নিজেই আমাদের জন্য ধারককরণ করে ?

আপনি যা ঘটছেন তার প্রসঙ্গে আপনি for comprehensionযে আইটেমটি সরবরাহ করেছেন তাতে একাধিক রূপান্তর হয় forযাতে আমরা আমাদের সমাবেশ লাইনের পরবর্তী কর্মীকে প্যাকেজিং নির্ধারণের ক্ষমতা দিচ্ছি। কল্পনা করুন আমাদের কাছে একটি সমাবেশ লাইন রয়েছে প্রতিটি শ্রমিক পণ্যটির জন্য কিছু করে এবং কেবল সর্বশেষ কর্মী এটি একটি পাত্রে প্যাকেজিং করছে! এটি স্বাগত জানাই flatMapএটির উদ্দেশ্য, mapপ্রতিটি কর্মীর মধ্যে আইটেমের কাজ শেষ হওয়ার পরে এটি প্যাকেজও করে দেয় যাতে আপনি পাত্রে পাত্রে পান।

বোধগম্য শক্তিমান

এখন আসুন আমরা উপরে যা বলেছিলাম তা বিবেচনায় নিয়ে আপনার বোধগম্যতার জন্য নজর দিন:

def bothMatch(pat:String,pat2:String,s:String):Option[Boolean] = for {
    f <- mkMatcher(pat)   
    g <- mkMatcher(pat2)
} yield f(s) && g(s)

আমরা এখানে কি পেয়েছি:

  1. mkMatcherধারকটিতে একটি containerফাংশন রয়েছে এমনটি প্রদান করে:String => Boolean
  2. বিধিগুলি হ'ল আমাদের যদি একাধিক থাকে তবে <-তারা flatMapশেষটি ব্যতীত অনুবাদ করে ।
  3. যেমনটি f <- mkMatcher(pat)প্রথম sequenceভাবেন (মনে করুন assembly line) আমরা এটির বাইরে যা চাই তা fসমাবেশ লাইনের পরবর্তী কর্মীর কাছে নিয়ে যাওয়া, আমরা আমাদের সমাবেশ লাইনের পরবর্তী কর্মীকে (পরবর্তী ফাংশন) যা হবে তা নির্ধারণ করার ক্ষমতাটি দেই আমাদের আইটেমের পিছনে প্যাকেজিং এই কারণেই শেষ ফাংশন map
  4. সর্বশেষ g <- mkMatcher(pat2)এটি ব্যবহার করবে mapকারণ এটি সর্বশেষে সমাবেশ লাইনে! সুতরাং এটি চূড়ান্ত অপারেশনটি করতে পারে map( g =>যার সাথে হ্যাঁ! আউট pulls gএবং ব্যবহার fযা ইতিমধ্যে দ্বারা ধারক থেকে টানা হয়েছে flatMapতাই আমরা প্রথম দিয়ে শেষ:

    এম কেম্যাচার (প্যাট) ফ্ল্যাটম্যাপ (এফ // টানুন এফ ফাংশনটি পরবর্তী এসেম্বলাইন লাইনের কর্মীদের আইটেম দিন (আপনি দেখতে পাচ্ছেন এটিতে অ্যাক্সেস রয়েছে fএবং এটি প্যাকেজ করবেন না) মানে মানচিত্রটি প্যাকেজিং নির্ধারণ করতে দেয় যে পরবর্তী সমাবেশ লাইনের কর্মী নির্ধারণ করতে দিন ধারক। mkMatcher (pat2) মানচিত্র (g => f (গুলি) ...)) // যেহেতু আমরা সমাবেশ লাইনে এটি শেষ ফাংশন হিসাবে আমরা মানচিত্রটি ব্যবহার করতে যাচ্ছি এবং ধারকটি থেকে জি টানতে এবং প্যাকেজিংয়ে ফিরে যাব , এটির mapএবং এই প্যাকেজিংটি পুরোপুরি থ্রোটল্ট হয়ে যাবে এবং আমাদের প্যাকেজ বা আমাদের পাত্রে থাকবে, হ্যাঁ!


4

যুক্তিটি হ'ল মোনাডিক অপারেশনগুলিকে শৃঙ্খলাবদ্ধ যা একটি সুবিধা হিসাবে প্রদান করে, যথাযথ "ব্যর্থ দ্রুত" ত্রুটি পরিচালনা করে।

এটা আসলে বেশ সহজ। mkMatcherপদ্ধতি একটি ফেরৎ Option(যা একটি একসংখ্যা যায়)। mkMatcherমোনাডিক অপারেশনের ফলাফলটি হয় এক Noneবা একটি Some(x)

mapবা সর্বদা flatMapফাংশন প্রয়োগ করা Noneসর্বদা একটি প্রদান করে None- ফাংশনটি প্যারামিটার হিসাবে পাস হয়েছে mapএবং flatMapমূল্যায়ন করা হয় না।

সুতরাং আপনার উদাহরণে, যদি mkMatcher(pat)কোনও কিছুই প্রদান করে না, তবে এটি প্রয়োগ করা ফ্ল্যাটম্যাপটি একটি None(দ্বিতীয় মনডিক অপারেশন mkMatcher(pat2)কার্যকর হবে না) mapফিরে আসবে এবং চূড়ান্তটি আবার একটিতে ফিরে আসবে None। অন্য কথায়, বোঝার জন্য অপারেশনগুলির মধ্যে যদি কোনওটি প্রদান করে না, আপনার একটি ব্যর্থ দ্রুত আচরণ রয়েছে এবং বাকী অপারেশনগুলি কার্যকর করা হয় না।

এটি ত্রুটি পরিচালনা করার monadic শৈলী। অপরিহার্য শৈলী ব্যতিক্রমগুলি ব্যবহার করে, যা মূলত লাফিয়ে লাফিয়ে থাকে (একটি ক্যাচ ক্লজে)

একটি চূড়ান্ত নোট: patternsফাংশনটি একটি অনিবার্য শৈলীর ত্রুটি হ্যান্ডলিং ( try... catch) ব্যবহার করে একটি monadic শৈলীর ত্রুটি হ্যান্ডলিং ব্যবহার করে "অনুবাদ" করার একটি সাধারণ উপায় usingOption


আপনি কি জানেন যে কেন flatMapএবং (এবং না map) প্রথম এবং দ্বিতীয় অনুরোধকে "একযোগে" ব্যবহার করতে ব্যবহৃত হয় mkMatcher, তবে কেন map(এবং না flatMap) দ্বিতীয় mkMatcherএবং yieldsব্লককে "কনকানেটেট" ব্যবহার করা হয় ?
মাল্টে শোওয়ারহফ

4
flatMapআপনি মোনাডে "মোড়ানো" / উত্তোলনের ফলাফল ফিরিয়ে ফাংশনটি পাস করার প্রত্যাশা করছেন, তবে mapমোড়ক / উত্তোলন নিজেই করবেন। ক্রিয়াকলাপগুলির কল শৃঙ্খলার সময় for comprehensionআপনার প্রয়োজন হয় flatmapযাতে প্যারামিটার হিসাবে পাস হওয়া ফাংশনগুলি ফিরে আসতে সক্ষম হয় None(আপনি মানটি কোনওটিতে তুলতে পারবেন না)। সর্বশেষ অপারেশন কল, যার মধ্যে একটি yieldচালিত হবে এবং একটি মান ফেরত প্রত্যাশা করবে ; একটি mapচেইন টু যে শেষ অপারেশন যথেষ্ট এবং এটি ফাংশনটির ফলাফলটি মোনাদে তুলতে হবে না।
ব্রুনো গ্রিডার

1

এটি ট্র্যাসলেট করা যেতে পারে:

def bothMatch(pat:String,pat2:String,s:String):Option[Boolean] = for {
    f <- mkMatcher(pat)  // for every element from this [list, array,tuple]
    g <- mkMatcher(pat2) // iterate through every iteration of pat
} yield f(s) && g(s)

এটি কীভাবে প্রসারিত হয়েছে তার আরও ভাল দেখার জন্য এটি চালান

def match items(pat:List[Int] ,pat2:List[Char]):Unit = for {
        f <- pat
        g <- pat2
} println(f +"->"+g)

bothMatch( (1 to 9).toList, ('a' to 'i').toList)

ফলাফলগুলি হ'ল:

1 -> a
1 -> b
1 -> c
...
2 -> a
2 -> b
...

এটি এর অনুরূপ flatMap- প্রতিটি উপাদানকে প্রতিটি উপাদানের মধ্যে লুপ করে patএবং mapএটিকে প্রতিটি উপাদানের সাথে পূর্বাভাস দেয়pat2


0

প্রথমে, mkMatcherএকটি ফাংশন ফিরিয়ে দেয় যার স্বাক্ষর String => Boolean, এটি একটি নিয়মিত জাভা পদ্ধতি যা সবেমাত্র চালানো হয় Pattern.compile(string), যেমন patternফাংশনে দেখানো হয়েছে । তারপরে, এই লাইনটি দেখুন

pattern(pat) map (p => (s:String) => p.matcher(s).matches)

mapফাংশনের ফলাফলের প্রয়োগ করা হয় pattern, যা Option[Pattern], তাই pমধ্যে p => xxxমাত্র প্যাটার্ন আপনি কম্পাইল করা হয়। সুতরাং, একটি প্যাটার্ন দেওয়া p, একটি নতুন ফাংশন নির্মিত হয়, যা একটি স্ট্রিং লাগে sএবং পরীক্ষা করে sযে প্যাটার্নটি মেলে কিনা।

(s: String) => p.matcher(s).matches

দ্রষ্টব্য, pচলকটি সংকলিত প্যাটার্নে আবদ্ধ। এখন, এটি স্বাক্ষর করে যে স্বাক্ষর সহ কোনও ফাংশন কীভাবে String => Booleanনির্মাণ করে mkMatcher

পরবর্তী, এর bothMatchউপর ভিত্তি করে ফাংশনটি চেকআউট করা যাক mkMatcher। কীভাবে bothMathchকাজ করে তা দেখাতে , আমরা প্রথমে এই অংশটি দেখি:

mkMatcher(pat2) map (g => f(s) && g(s))

যেহেতু আমরা স্বাক্ষর সহ একটি ফাংশন পেয়েছিলাম String => Booleanথেকে mkMatcher, যা gএ প্রসঙ্গে g(s)সমতূল্য Pattern.compile(pat2).macher(s).matches, যা আয় যদি স্ট্রিং গুলি ম্যাচ প্যাটার্ন pat2। সুতরাং কিভাবে সম্পর্কে f(s), এটি একই হিসাবে g(s), শুধু পার্থক্য যে প্রথম কল করা হয়, mkMatcherব্যবহারের flatMapপরিবর্তে map, কেন? যেহেতু mkMatcher(pat2) map (g => ....)রিটার্ন Option[Boolean], আপনি উভয় কলের জন্য Option[Option[Boolean]]ব্যবহার করলে আপনি নেস্টেড ফলাফল পাবেন map, এটি আপনি চান তা নয়।

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