2014-09-14 5 views
48

मान लीजिए मैं एक प्रकार वर्ग साबित करता है कि वह सब एक निराकार 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 मैक्रो विधि द्वारा उत्पन्न (जिसे हम उन्हें बनाने के लिए उपयोग करते थे) नहीं करते हैं। यहाँ क्या चल रहा है? क्या कोई सुविधाजनक कामकाज है जिसके लिए हमें रचनाकारों को मैन्युअल रूप से गणना करने की आवश्यकता नहीं है?

+1

मैंने हाल ही में इस क्षेत्र में कुछ कीड़े तय की हैं ... नवीनतम स्नैपशॉट के साथ पुनः प्रयास करें? –

+0

हम्म, कोई भाग्य-एक ही परिणाम नहीं। –

+2

अधिक tweaks आज धक्का दिया ... तीसरी बार भाग्यशाली? –

उत्तर

22

यह सबसे हालिया आकारहीन 2.1.0-स्नैपशॉट के रूप में लिखा गया है।

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