के अंदर एक टुपल कैसे वापस करें मैं स्कालज़ 7 के ईटीटीटी का उपयोग कर रहा हूं ताकि समझदारी के लिए राज्य और \ /। अब तक सब ठीक है; मैं कुछ मूल रूप से है कि मिल:एक ईटटी
State[MyStateType, MyLeftType \/ MyRightType]
और यह मेरे लिए-comprehensions < की बाईं ओर अच्छा चर है कि निर्माण करने के लिए अनुमति देता है -।
लेकिन मैं यह नहीं समझ सकता कि राज्य कार्रवाई से टुपल कैसे वापस करें। एकल परिणाम ठीक हैं - नीचे दिए गए कोड में, "वैल समझ" बिल्कुल वही है जो मैं करना चाहता हूं।
लेकिन जब मैं एक ट्यूपल वापस करना चाहता हूं तो चीजें अलग हो जाती हैं; "वैल otherComprehension" मुझे
(a, b) <- comprehension
कर ऐसा लगता है कि यह \ के बाईं ओर उम्मीद/एक monoid होने के लिए और मैं क्यों समझ में नहीं आता नहीं दूँगा। मैं क्या खो रहा हूँ?
(Scalaz 7 2.0.0-स्नैपशॉट, स्काला 2.10.2)
object StateProblem {
case class MyStateType
case class MyRightType
case class MyLeftType
type StateWithFixedStateType[+A] = State[MyStateType, A]
type EitherTWithFailureType[F[+_], A] = EitherT[F, MyLeftType, A]
type CombinedStateAndFailure[A] = EitherTWithFailureType[StateWithFixedStateType, A]
def doSomething: CombinedStateAndFailure[MyRightType] = {
val x = State[MyStateType, MyLeftType \/ MyRightType] {
case s => (s, MyRightType().right)
}
EitherT[StateWithFixedStateType, MyLeftType, MyRightType](x)
}
val comprehension = for {
a <- doSomething
b <- doSomething
} yield (a, b)
val otherComprehension = for {
// this gets a compile error:
// could not find implicit value for parameter M: scalaz.Monoid[com.seattleglassware.StateProblem.MyLeftType]
(x, y) <- comprehension
z <- doSomething
} yield (x, y, z)
}
संपादित करें: मैं सबूत है कि MyLeftType, एक इकाई है, भले ही यह नहीं है जोड़ दिया है। मेरा असली कोड में, MyLeftType एक मामले वर्ग (EarlyReturn कहा जाता है) है, इसलिए मैं एक शून्य प्रदान कर सकते हैं, लेकिन संलग्न तभी काम करता है तर्कों में से एक एक शून्य है:
implicit val partialMonoidForEarlyReturn = new Monoid[EarlyReturn] {
case object NoOp extends EarlyReturn
def zero = NoOp
def append(a: EarlyReturn, b: => EarlyReturn) =
(a, b) match {
case (NoOp, b) => b
case (a, NoOp) => a
case _ => throw new RuntimeException("""this isnt really a Monoid, I just want to use it on the left side of a \/""")
}
}
मैं इस आश्वस्त नहीं कर रहा हूँ एक है अच्छा विचार है, लेकिन यह समस्या को हल कर रहा है।
for {
//(x, y) <- comprehension
p <- comprehension
z <- doSomething
} yield (p._1, p._2, z)
या शायद थोड़ा बेहतर
for {
//(x, y) <- comprehension
p <- comprehension
(x, y) = p
z <- doSomething
} yield (x, y, z)
यह बहुत अच्छा नहीं है, लेकिन काम करता है:
रास्ते में कुछ अजीब चल रहा है 2.10.1+ यहां 'समझ' के लिए 'इस सवाल] (http://stackoverflow.com/q/17424763/334519) के सरलीकृत संस्करण के लिए desugars वही मुद्दा। –
और स्पष्ट होने के लिए, ऐसा इसलिए हो रहा है क्योंकि 'EitherT' (या' \/') को फ़िल्टर करने के लिए बाईं तरफ एक मोनोइड आवृत्ति की आवश्यकता होती है, और किसी कारण से 2.10.2 इस 'समझ' में फ़िल्टर ऑपरेशन चिपका रहा है। –