नीचे दिए गए कोड अंश में, अंतिम कथन संकलित नहीं होता है। हालांकि, उससे ठीक पहले का बयान वास्तव में संकलित करता है। यह दूसरा-से-अंतिम कथन है जो मैं अपेक्षा करता हूं कि संकलक अंतिम कथन को परिवर्तित कर देगा। मुझे समझ में नहीं आता कि यह क्यों काम नहीं करता है। किसी भी मदद की सराहना की जाती है।

trait ParameterizedBy[A, B] {
    val parameterized: B
  }

object ParameterizedBy {
  implicit def toParameterized[A, B, C](p: ParameterizedBy[A, B])(
    implicit f: B => C): C = f(p.parameterized)
}

trait Wraps[A] {
  val wrapped: A
}

object Wraps {
  implicit def toWrapped[A](w: Wraps[A]): A = w.wrapped
}

val p = new ParameterizedBy[String, Wraps[Int]] {
  override val parameterized: Wraps[Int] = new Wraps[Int] {
    override val wrapped = 6
  }
}

ParameterizedBy.toParameterized(p)(Wraps.toWrapped) + 5

p + 5
1
N W 29 अक्टूबर 2018, 04:13

1 उत्तर

सबसे बढ़िया उत्तर

किसी विधि को अस्पष्ट रूप से A => C में परिवर्तित करना समस्याग्रस्त है, क्योंकि संकलक आसानी से सभी संभावित वर्गों C की गणना नहीं कर सकता है जिनकी अपेक्षित विधि + है, और फिर जाएं और सभी संभावित तरीकों को खोजें जो B लेते हैं और C देते हैं - यह खोज हमेशा के लिए लेगी।

मैं अज्ञात प्रकार C के लिए B => C प्रकार के निहित तर्कों से बचने का सुझाव दूंगा। यदि आप एक कनवर्टर चाहते हैं, तो उसे कुछ विशिष्ट नाम दें, उदा।

trait Unwrap[A, B] extends (A => B)

कि आप तब केवल इस जंजीर निहित में उपयोग करते हैं।

इसके बजाय आप जो कोशिश कर सकते हैं उसका एक मोटा स्केच:

import scala.language.implicitConversions

trait ParameterizedBy[A, B] {
    val parameterized: B
  }

object ParameterizedBy {
  implicit def toParameterized[A, B, C](p: ParameterizedBy[A, B])(
    implicit f: Unwrap[B, C]): C = f(p.parameterized)
}

trait Wraps[A] {
  val wrapped: A
}

object Wraps {
  implicit def toWrapped[A](w: Wraps[A]): A = w.wrapped
}

trait Unwrap[A, B] extends (A => B)

object Unwrap {
  implicit def unwrap[A]: Unwrap[Wraps[A], A] = new Unwrap[Wraps[A], A] {
    def apply(w: Wraps[A]): A = w.wrapped
  }
}

val p = new ParameterizedBy[String, Wraps[Int]] {
  override val parameterized: Wraps[Int] = new Wraps[Int] {
    override val wrapped = 6
  }
}

p - 5         // works
(p: Int) + 5  // works with type ascription (to avoid conflicts with `+ String`)
1
Andrey Tyukin 29 अक्टूबर 2018, 01:38