2015-08-19 11 views
8

यह संकलित क्यों नहीं करता है?बिज़ारे प्रकार अनुमान सीमा - एकाधिक प्रकार पैराम

trait Lol[A, SA] { 
    def flatMap[B, SB](f: A => Lol[B, SB]): Lol[B, SB] = ??? 
} 

val p1: Lol[Int, String] = ??? 
val p2: Lol[Double, Nothing] = ??? 

val p5 = p1.flatMap(_ => p2) 

परिणाम:

found : Int => Lol[Double,Nothing] 
required: Int => Lol[Double,SB] 
    val p5 = p1.flatMap(_ => p2) 
         ^ 

हालात संकलित करने के लिए है जब या तो शुरू: (? WTF)

flatMap मंगलाचरण के
  • प्रकार पैरामीटर स्पष्ट कर रहे हैं
  • SA covariant है
  • कुछ Nothing से अन्य प्रकार हम हैं p2 में एड (उदा। Null)
  • SBflatMap की वापसी प्रकार में पाए जाते हैं या (जैसे वापसी प्रकार Option[SB] है)

कि वापसी प्रकार की covariant स्थिति से ऊपर समाधान हालांकि मेरे लिए स्वीकार्य नहीं हैं में होता नहीं है।

+1

भिन्नता आपके लिए कोई विकल्प क्यों नहीं है? आमतौर पर जहां संभव हो भिन्नता का उपयोग करना एक अच्छा विचार है। 'कुछ भी नहीं' का उपयोग अधिकांश समय केवल भिन्नता के तहत समझ में आता है। –

+0

@ 0__ 'SA' बस पूर्ण एपीआई (यहां दिखाया नहीं गया) को कॉन्वेंट नहीं किया जा सकता है। हालांकि - आप 'कुछ भी नहीं' के बारे में सही हैं - यदि 'एसए' संविधान नहीं है, तो शायद मैं 'कुछ भी नहीं' – ghik

+1

का उपयोग करने के बजाय अपना खुद का विशेष प्रकार बना सकता हूं, फिर भी, यह त्रुटि अभी भी हास्यास्पद रूप से बिगड़ और एक बग की गंध है। – ghik

उत्तर

2

SI-9453 पर पुनर्नवीनीकरण की टिप्पणी @ जो व्यवहार आप देख रहे हैं उसे बताते हैं। यहाँ एक तरह के वैकल्पिक हल ...

हम Nothing करने के लिए एक प्रकार बराबर संश्लेषण कर सकते हैं जो टाइपकर्ता अनुमान समाधान वापस लेना का कारण नहीं बनेगा,

type ReallyNothing = Nothing { type T = Unit } 

यानी है। एक डमी परिष्करण के साथ Nothing। अब प्रश्न के उदाहरण के साथ,

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

trait Lol[A, SA] { 
    def flatMap[B, SB](f: A => Lol[B, SB]): Lol[B, SB] = ??? 
} 

val p1: Lol[Int, String] = ??? 
val p2: Lol[Double, ReallyNothing] = ??? 

val p5 = p1.flatMap(_ => p2) 

// Exiting paste mode, now interpreting. 

scala.NotImplementedError: an implementation is missing 
    at scala.Predef$.$qmark$qmark$qmark(Predef.scala:225) 
    ... 37 elided 
2

आदेश में बेहतर आपकी समस्या को समझने के लिए, यह सरल किया जा सकता है:

class Lol[A] 
def foo[B](f: Lol[B]) = f 
foo(new Lol[Nothing]) 

जो आप निम्नलिखित संकलन त्रुटि देता है:

error: type mismatch; 
found : Lol[Nothing] 
required: Lol[B] 
Note: Nothing <: B, but class Lol is invariant in type A. 
You may wish to define A as +A instead. (SLS 4.5) 

सम्भावित समाधान ऐसा स्निपेट अपडेट करना है :

def foo[B <: Lol[_]](f: B) = f 

अपने मूल कोड पर वापस जाएं:

trait Lol[A, SA] { 
    def flatMap[B <: Lol[_,_]](f: A => B): B = ??? 
} 
संबंधित मुद्दे