कुछ उपयोग हैं:
PartialFunction
याद रखें एक PartialFunction[A, B]फ़ंक्शन डोमेन के कुछ सबसेट के लिए परिभाषित किया गया है A(जैसा कि isDefinedAtविधि द्वारा निर्दिष्ट है )। आप एक 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के डोमेन में फ़ंक्शन को "लिफ्ट" करने में सक्षम है । अर्थात्:
def lift[F[_]: Functor, A, B](f: A => B): F[A] => F[B]
यही है, अगर Fएक फ़नकार है, और हमारे पास एक फ़ंक्शन है A => B, तो हमारे पास एक फ़ंक्शन है F[A] => F[B]। आप कोशिश कर सकते हैं और liftविधि को लागू कर सकते हैं - यह बहुत तुच्छ है।
मोनाड ट्रांसफॉर्मर
जैसा कि hcoopz नीचे कहता है (और मुझे अभी पता चला है कि इससे मुझे एक टन अनावश्यक कोड लिखने से बचाया गया होगा), "लिफ्ट" शब्द का भी मोनाड ट्रांसफॉर्मर्स के भीतर एक अर्थ है । स्मरण करो कि एक भिक्षु ट्रांसफार्मर एक दूसरे के शीर्ष पर "स्टैकिंग" मठों का एक तरीका है (मठ रचना नहीं करते हैं)।
इसलिए, उदाहरण के लिए, मान लीजिए कि आपके पास एक फ़ंक्शन है जो एक रिटर्न देता है IO[Stream[A]]। इसे मोनड ट्रांसफार्मर में परिवर्तित किया जा सकता है StreamT[IO, A]। अब आप शायद कुछ और "मूल्य" उठाना IO[B]चाहते हैं कि यह भी एक है StreamT। आप इसे लिख सकते हैं:
StreamT.fromStream(iob map (b => Stream(b)))
या यह:
iob.liftM[StreamT]
यह सवाल है: क्यों मैं एक 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]