2015-12-31 6 views
8

को Option पर इसी तरह से संभालना संभव है? Option में, मेरे पास getOrElse फ़ंक्शन है, Either में मैं Left वापस करना चाहता हूं या Right पर प्रक्रिया करना चाहता हूं। मैं किसी भी तरह बॉयलरप्लेट के बिना ऐसा करने का सबसे तेज़ तरीका है के लिए देख रहा हूँ:स्कैला या तो नक्शा दाएं या वापस बाएं

val myEither:Either[String, Object] = Right(new Object()) 
myEither match { 
    case Left(leftValue) => value 
    case Right(righValue) => 
     "Success" 
} 

उत्तर

1

मुझे लगता है कि आप इस प्रकार कर सकते हैं।

def foo(myEither: Either[String, Object]) = 
    myEither.right.map(rightValue => "Success") 
+0

ऐसा लगता है कि 'foo' को' स्ट्रिंग 'वापस करना चाहिए, न कि' या तो '। क्या आप अंत में '.getOrElse (मान) 'नहीं खो रहे हैं? – Marth

+0

"या तो मैं बाएं या प्रक्रिया दाएं वापस करना चाहता हूं" सही प्रक्षेपण मैपिंग द्वारा किया जाता है। 'या तो [ए, बी]' के लिए लक्ष्य 'ए' प्राप्त करना है ('दाएं' के लिए 'बी => ए' प्रदान किया गया है) या' बी' ('ए => बी 'प्रदान किया गया है' बाएं '), फिर '.fold' आपका मित्र है। – cchantep

+0

आप सही हैं, मैंने सवाल बहुत जल्दी पढ़ा। मैंने बस उसमें कोड देखा और सोचा कि सवाल "मैं इसे और अधिक संक्षेप में कैसे लिखूं"। मेरी गलती। – Marth

3

आप .fold उपयोग कर सकते हैं:

scala> val r: Either[Int, String] = Right("hello") 
r: Either[Int,String] = Right(hello) 

scala> r.fold(_ => "got a left", _ => "Success") 
res7: String = Success 

scala> val l: Either[Int, String] = Left(1) 
l: Either[Int,String] = Left(1) 

scala> l.fold(_ => "got a left", _ => "Success") 
res8: String = got a left 

संपादित करें:

फिर से पढ़ने अपने प्रश्न यह मेरे लिए स्पष्ट नहीं है कि आप Left या एक और एक में मूल्य वापस करना चाहते हैं (कहीं और परिभाषित)
यदि यह पूर्व है, तो आप identity से .fold पास कर सकते हैं, हो wever इस Any को वापसी प्रकार बदल सकता है:

scala> r.fold(identity, _ => "Success") 
res9: Any = Success 
4

दोनों 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) 
    } 
} 

सब तो प्रसंस्करण चरण सफल हुए, locPopPairRight[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 वापस करना चाहते हैं जो "खाली" का प्रतीक है, लेकिन कोई सार्वभौमिक उचित मूल्य नहीं है (सभी LeftLeft[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") हो जाएगा।

संबंधित मुद्दे