दोनों cchantep की और Marth के अपने तत्काल समस्या के लिए अच्छा समाधान कर रहे हैं। लेकिन अधिक व्यापक रूप से, Option
पर पूरी तरह से समान कुछ के रूप में व्यवहार करना मुश्किल है, विशेष रूप से आपको समझ के लिए संभावित रूप से उपलब्ध कंप्यूटेशंस के स्पष्ट अनुक्रम देने में। या तो एक प्रक्षेपण API है (cchantep के समाधान में उपयोग किया जाता है), लेकिन यह थोड़ा टूटा हुआ है। (या तो गार्ड, पैटर्न मिलान, या परिवर्तनीय असाइनमेंट के साथ समझ के लिए अनुमानों में ब्रेक लग रहा है।)
FWIW, मैंने इस समस्या को हल करने के लिए library लिखा है। यह this API के साथ या तो बढ़ाता है। आप अपने ईथर के लिए "पूर्वाग्रह" परिभाषित करते हैं। "दायां पूर्वाग्रह" का अर्थ है कि सामान्य प्रवाह (मानचित्र, प्राप्त, आदि) को Right
ऑब्जेक्ट द्वारा दर्शाया जाता है जबकि Left
ऑब्जेक्ट्स किसी प्रकार की समस्या का प्रतिनिधित्व करते हैं। (दायां पूर्वाग्रह परंपरागत है, हालांकि यदि आप चाहें तो बाएं पूर्वाग्रह को भी परिभाषित कर सकते हैं।) फिर आप का इलाज Option
जैसे कर सकते हैं; यह एक पूरी तरह से अनुरूप एपीआई offsers।
import com.mchange.leftright.BiasedEither
import BiasedEither.RightBias._
val myEither:Either[String, Object] = ...
val o = myEither.getOrElse("Substitute")
अधिक उपयोगी, अब आप का इलाज कर सकते या तो एक सच्चे स्केला इकाई, यानी की तरह flatMap, नक्शे, फिल्टर, और comprehensions के लिए उपयोग करें:
val myEither : Either[String, Point] = ???
val nextEither = myEither.map(_.x) // Either[String,Int]
या
val myEither : Either[String, Point] = ???
def findGalaxyAtPoint(p : Point) : Either[String,Galaxy] = ???
val locPopPair : Either[String, (Point, Long)] = {
for {
p <- myEither
g <- findGalaxyAtPoint(p)
} yield {
(p, g.population)
}
}
सब तो प्रसंस्करण चरण सफल हुए, locPopPair
Right[Long]
होगा। अगर कुछ गलत हो गया, तो यह पहला Left[String]
सामने आएगा।
यह थोड़ा अधिक जटिल है, लेकिन एक खाली टोकन को परिभाषित करने का एक अच्छा विचार है। के ऊपर समझ के लिए पर एक मामूली बदलाव पर नजर डालते हैं:
val locPopPair : Either[String, (Point, Long)] = {
for {
p <- myEither
g <- findGalaxyAtPoint(p) if p.x > 1000
} yield {
(p, g.population)
}
}
क्या होगा यदि परीक्षण p.x > 1000
में विफल रहा है? हम कुछ Left
वापस करना चाहते हैं जो "खाली" का प्रतीक है, लेकिन कोई सार्वभौमिक उचित मूल्य नहीं है (सभी Left
Left[String]
नहीं हैं।अभी तक, कोड क्या होगा NoSuchElementException
फेंक देगा। लेकिन हम एक खाली टोकन खुद, जैसा कि नीचे निर्दिष्ट कर सकते हैं:
import com.mchange.leftright.BiasedEither
val RightBias = BiasedEither.RightBias.withEmptyToken[String]("EMPTY")
import RightBias._
val myEither : Either[String, Point] = ???
def findGalaxyAtPoint(p : Point) : Either[String,Galaxy] = ???
val locPopPair : Either[String, (Point, Long)] = {
for {
p <- myEither
g <- findGalaxyAtPoint(p) if p.x > 1000
} yield {
(p, g.population)
}
}
अब, अगर p.x > 1000
परीक्षण विफल रहता है, वहाँ कोई अपवाद नहीं होगा, locPopPair
सिर्फ Left("EMPTY")
हो जाएगा।
ऐसा लगता है कि 'foo' को' स्ट्रिंग 'वापस करना चाहिए, न कि' या तो '। क्या आप अंत में '.getOrElse (मान) 'नहीं खो रहे हैं? – Marth
"या तो मैं बाएं या प्रक्रिया दाएं वापस करना चाहता हूं" सही प्रक्षेपण मैपिंग द्वारा किया जाता है। 'या तो [ए, बी]' के लिए लक्ष्य 'ए' प्राप्त करना है ('दाएं' के लिए 'बी => ए' प्रदान किया गया है) या' बी' ('ए => बी 'प्रदान किया गया है' बाएं '), फिर '.fold' आपका मित्र है। – cchantep
आप सही हैं, मैंने सवाल बहुत जल्दी पढ़ा। मैंने बस उसमें कोड देखा और सोचा कि सवाल "मैं इसे और अधिक संक्षेप में कैसे लिखूं"। मेरी गलती। – Marth