টিএল; ডিআর সরাসরি চূড়ান্ত উদাহরণে যান
আমি চেষ্টা করব এবং পুনরুদ্ধার করব।
সংজ্ঞা
forধী একত্রিত করতে একটি বাক্য গঠন শর্টকাট flatMapএবং mapএকটি উপায় পড়া এবং প্রায় কারণ সহজে হবে।
আসুন জিনিসগুলি কিছুটা সহজ করুন এবং ধরে নেওয়া যাক যে classউভয়টি পূর্বোক্ত উভয় পদ্ধতি সরবরাহ করে তাকে একটি বলা যেতে পারে monadএবং আমরা প্রতীকটি একটি অভ্যন্তরের প্রকারের সাথে M[A]বোঝাতে ব্যবহার করব ।monadA
উদাহরণ
কিছু সাধারণভাবে দেখা মনদের মধ্যে রয়েছে:
List[String] কোথায়
M[X] = List[X]
A = String
Option[Int] কোথায়
Future[String => Boolean] কোথায়
M[X] = Future[X]
A = (String => Boolean)
মানচিত্র এবং ফ্ল্যাটম্যাপ
জেনেরিক মোনাডে সংজ্ঞায়িত M[A]
def map(f: A => B): M[B]
def flatMap(f: A => M[B]): M[B]
যেমন
val list = List("neo", "smith", "trinity")
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)
প্রকাশের জন্য
<-প্রতীক ব্যবহার করে এক্সপ্রেশনটির প্রতিটি লাইন একটি flatMapকলটিতে অনুবাদ করা হয় , শেষ পংক্তির পরিবর্তে একটি শেষ mapকলটিতে অনুবাদ করা হয় , যেখানে বাম-হাতের "সীমাবদ্ধ চিহ্ন" আর্গুমেন্ট ফাংশনের প্যারামিটার হিসাবে পাস হয় (কী আমরা পূর্বে ডেকেছি f: A => M[B]):
for {
bound <- list
out <- f(bound)
} yield out
list.flatMap { bound =>
f(bound).map { out =>
out
}
}
list.flatMap { bound =>
f(bound)
}
list flatMap f
শুধুমাত্র একটির সাথে একটি অভিব্যক্তিকে যুক্তিতে <-রূপান্তরিত অভিব্যক্তিটির সাথে একটি mapকলে রূপান্তরিত হয় :
for {
bound <- list
} yield f(bound)
list.map { bound =>
f(bound)
}
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]