मान लीजिए मैं एक प्रकार वर्ग साबित करता है कि वह सब एक निराकार coproduct में प्रकार सिंगलटन प्रकार के होते हैं मिल गया है:साबित नहीं किया जा सकता है कि सिंगलटन प्रकार सिंगलटन प्रकार प्रकार वर्ग उदाहरण जनरेट करते समय कर रहे हैं
import shapeless._
trait AllSingletons[A, C <: Coproduct] {
def values: List[A]
}
object AllSingletons {
implicit def cnilSingletons[A]: AllSingletons[A, CNil] =
new AllSingletons[A, CNil] {
def values = Nil
}
implicit def coproductSingletons[A, H <: A, T <: Coproduct](implicit
tsc: AllSingletons[A, T],
witness: Witness.Aux[H]
): AllSingletons[A, H :+: T] =
new AllSingletons[A, H :+: T] {
def values = witness.value :: tsc.values
}
}
हम दिखा सकते हैं
sealed trait Foo
case object Bar extends Foo
case object Baz extends Foo
और फिर:
scala> implicitly[AllSingletons[Foo, Bar.type :+: Baz.type :+: CNil]].values
res0: List[Foo] = List(Bar, Baz)
अब हम कंघी करना चाहते हैं यह एक साधारण एडीटी के साथ काम करता है कि निराकार के Generic
तंत्र के साथ यह है कि हमें हमारे एडीटी के coproduct प्रतिनिधित्व दे देंगे ऑफ़लाइन:
trait EnumerableAdt[A] {
def values: Set[A]
}
object EnumerableAdt {
implicit def fromAllSingletons[A, C <: Coproduct](implicit
gen: Generic.Aux[A, C],
singletons: AllSingletons[A, C]
): EnumerableAdt[A] =
new EnumerableAdt[A] {
def values = singletons.values.toSet
}
}
मैं implicitly[EnumerableAdt[Foo]]
काम करने के लिए उम्मीद थी, लेकिन ऐसा नहीं है। हम क्यों के बारे में कुछ जानकारी प्राप्त करना -Xlog-implicits
उपयोग कर सकते हैं:
<console>:17: shapeless.this.Witness.apply is not a valid implicit value for
shapeless.Witness.Aux[Baz.type] because:
Type argument Baz.type is not a singleton type
implicitly[EnumerableAdt[Foo]]
^
<console>:17: this.AllSingletons.coproductSingletons is not a valid implicit
value for AllSingletons[Foo,shapeless.:+:[Baz.type,shapeless.CNil]] because:
hasMatchingSymbol reported error: could not find implicit value for parameter
witness: shapeless.Witness.Aux[Baz.type]
implicitly[EnumerableAdt[Foo]]
^
<console>:17: this.AllSingletons.coproductSingletons is not a valid implicit
value for AllSingletons[Foo,this.Repr] because:
hasMatchingSymbol reported error: could not find implicit value for parameter
tsc: AllSingletons[Foo,shapeless.:+:[Baz.type,shapeless.CNil]]
implicitly[EnumerableAdt[Foo]]
^
<console>:17: this.EnumerableAdt.fromAllSingletons is not a valid implicit
value for EnumerableAdt[Foo] because:
hasMatchingSymbol reported error: could not find implicit value for parameter
singletons: AllSingletons[Foo,C]
implicitly[EnumerableAdt[Foo]]
^
<console>:17: error: could not find implicit value for parameter e:
EnumerableAdt[Foo]
implicitly[EnumerableAdt[Foo]]
^
Baz.type
जाहिर , एक सिंगलटन प्रकार है, हालांकि। हम सिर्फ मनोरंजन के लिए मैन्युअल रूप से दायरे में Witness
उदाहरणों डालने की कोशिश कर सकते हैं:
implicit val barSingleton = Witness[Bar.type]
implicit val bazSingleton = Witness[Baz.type]
और किसी भी तरह अब यह काम करता है:
scala> implicitly[EnumerableAdt[Foo]].values
res1: Set[Foo] = Set(Bar, Baz)
मुझे समझ नहीं आता क्यों इन उदाहरणों इस संदर्भ जबकि लोगों में काम करेगा Witness.apply
मैक्रो विधि द्वारा उत्पन्न (जिसे हम उन्हें बनाने के लिए उपयोग करते थे) नहीं करते हैं। यहाँ क्या चल रहा है? क्या कोई सुविधाजनक कामकाज है जिसके लिए हमें रचनाकारों को मैन्युअल रूप से गणना करने की आवश्यकता नहीं है?
मैंने हाल ही में इस क्षेत्र में कुछ कीड़े तय की हैं ... नवीनतम स्नैपशॉट के साथ पुनः प्रयास करें? –
हम्म, कोई भाग्य-एक ही परिणाम नहीं। –
अधिक tweaks आज धक्का दिया ... तीसरी बार भाग्यशाली? –