কয়েকটি ব্যবহার রয়েছে:
PartialFunction
মনে রাখবেন একটি PartialFunction[A, B]
ডোমেনের কিছু উপসেটের জন্য A
( isDefinedAt
পদ্ধতি দ্বারা নির্দিষ্ট হিসাবে ) সংজ্ঞায়িত করা একটি ফাংশন Remember আপনি "লিফট" একটি পারেন PartialFunction[A, B]
একটি মধ্যে Function[A, Option[B]]
। অর্থাৎ একটি ফাংশন উপর সংজ্ঞায়িত পুরো এর A
কিন্তু যাদের মান ধরনেরOption[B]
এই পদ্ধতি বর্ণিত আবাহন দ্বারা সম্পন্ন করা হয় lift
উপর PartialFunction
।
scala> val pf: PartialFunction[Int, Boolean] = { case i if i > 0 => i % 2 == 0}
pf: PartialFunction[Int,Boolean] = <function1>
scala> pf.lift
res1: Int => Option[Boolean] = <function1>
scala> res1(-1)
res2: Option[Boolean] = None
scala> res1(1)
res3: Option[Boolean] = Some(false)
পদ্ধতি
আপনি কোনও ফাংশনে কোনও পদ্ধতিতে অনুরোধ "উত্তোলন" করতে পারেন। একে বলা হয় এটা-এক্সপেনশন (এর জন্য বেন জেমসকে ধন্যবাদ)। উদাহরণস্বরূপ:
scala> def times2(i: Int) = i * 2
times2: (i: Int)Int
আমরা আন্ডারস্কোর প্রয়োগ করে একটি পদ্ধতিতে একটি পদ্ধতি উত্তোলন করি
scala> val f = times2 _
f: Int => Int = <function1>
scala> f(4)
res0: Int = 8
পদ্ধতি এবং কার্যকারিতা মধ্যে মৌলিক পার্থক্য নোট করুন। res0
একজন উদাহরণস্বরূপ (অর্থাত এটি একটি হল মান (ফাংশন) ধরনের)(Int => Int)
Functors
একজন functor (যেমন দ্বারা সংজ্ঞায়িত scalaz ) কিছু "ধারক" (আমি শব্দ ব্যবহার করেন অত্যন্ত ঢিলেঢালাভাবে), F
যেমন যে, যদি আমরা একটি আছে F[A]
এবং একটি ফাংশন A => B
, তাহলে আমরা আমাদের হাতে একটি পেতে পারেন F[B]
(মনে করি, উদাহরণস্বরূপ, F = List
এবং map
পদ্ধতি )
আমরা এই সম্পত্তিটি নিম্নলিখিতভাবে এনকোড করতে পারি:
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
এটি ফ্যান্টারের A => B
ডোমেনে ফাংশনটি "উত্তোলন" করতে সক্ষম হওয়ায় isomorphic । এটাই:
def lift[F[_]: Functor, A, B](f: A => B): F[A] => F[B]
এটি হ'ল যদি F
কোনও ফান্টেক্টর হয় এবং আমাদের একটি ফাংশন A => B
থাকে তবে আমাদের একটি ফাংশন থাকে F[A] => F[B]
। আপনি lift
পদ্ধতিটি প্রয়োগ করে প্রয়োগ করতে পারেন - এটি বেশ তুচ্ছ।
মোনাড ট্রান্সফর্মারস
যেমন এইচসিওপিজ নীচে বলেছেন (এবং আমি ঠিক বুঝতে পেরেছি যে এটি আমাকে এক টন অপ্রয়োজনীয় কোড লেখার হাত থেকে বাঁচিয়েছে), মোনাড ট্রান্সফরমারগুলির মধ্যে "লিফট" শব্দটিরও একটি অর্থ রয়েছে । মনে রাখবেন যে একটি মোনাড ট্রান্সফর্মার একে অপরের শীর্ষে "স্ট্যাকিং" মোনাদগুলির একটি উপায় (মনডগুলি রচনা করে না)।
উদাহরণস্বরূপ, ধরুন আপনার একটি ফাংশন রয়েছে যা একটি প্রদান করে IO[Stream[A]]
। এটি মোনাড ট্রান্সফর্মারে রূপান্তরিত হতে পারে StreamT[IO, A]
। এখন আপনি "লিফট" থেকে কিছু অন্যান্য মান পারেন একটি IO[B]
সম্ভবত যে এটি একটি হল StreamT
। আপনি হয় এটি লিখতে পারে:
StreamT.fromStream(iob map (b => Stream(b)))
অথবা এটা:
iob.liftM[StreamT]
: এই প্রশ্ন begs কেন আমি একজন রূপান্তর করতে চাও IO[B]
একটি মধ্যে StreamT[IO, B]
? । উত্তরটি হবে "রচনা সম্ভাবনার সুযোগ নেওয়া"। ধরা যাক আপনার একটি ফাংশন আছেf: (A, B) => C
lazy val f: (A, B) => C = ???
val cs =
for {
a <- as //as is a StreamT[IO, A]
b <- bs.liftM[StreamT] //bs was just an IO[B]
}
yield f(a, b)
cs.toStream //is a Stream[IO[C]], cs was a StreamT[IO, C]