টিএল; ডিআর সরাসরি চূড়ান্ত উদাহরণে যান
আমি চেষ্টা করব এবং পুনরুদ্ধার করব।
সংজ্ঞা
for
ধী একত্রিত করতে একটি বাক্য গঠন শর্টকাট flatMap
এবং map
একটি উপায় পড়া এবং প্রায় কারণ সহজে হবে।
আসুন জিনিসগুলি কিছুটা সহজ করুন এবং ধরে নেওয়া যাক যে class
উভয়টি পূর্বোক্ত উভয় পদ্ধতি সরবরাহ করে তাকে একটি বলা যেতে পারে monad
এবং আমরা প্রতীকটি একটি অভ্যন্তরের প্রকারের সাথে M[A]
বোঝাতে ব্যবহার করব ।monad
A
উদাহরণ
কিছু সাধারণভাবে দেখা মনদের মধ্যে রয়েছে:
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]