2012-12-17 5 views
11

का उपयोग कर निम्नलिखित सार एक विचार मैंमुद्दे के समाधान arity सूची प्रसंस्करण ड्राइव करने के लिए, निराकार

package com.test1 

import scala.language.implicitConversions 
import shapeless._ 
import FromTraversable._ 
import Traversables._ 
import Nat._ 
import Tuples._ 

trait ToArity[P, N <: Nat] 

object ToArity { 
    implicit def prod1[P <: Product1[_]] = new ToArity[P, _1] {} 
    implicit def prod2[P <: Product2[_, _]] = new ToArity[P, _2] {} 
    // ad nauseum... 
} 

trait SizedHListAux[A, N <: Nat, T <: HList] 

object SizedHListAux { 
    implicit def base[A, H <: HList] = new SizedHListAux[A, _0, HNil] {} 
    implicit def induct[A, H <: HList, N <: Nat, P <: Nat](implicit r: PredAux[N,P], k: SizedHListAux[A, P, H]) = new SizedHListAux[A, N, A :: H] {} 
} 

trait SomeFun { 
    type Result 
    def apply(): Result 
} 

// I want to abstract over A, the contained type in the List 
// over P the Product type which is the arg notably its arity 
// This means we need to recover arity of the Product type and render it in value space 
// and also means that we need to compute the type of the intermediate HList 
object SomeFun { 
    def produce(m: SomeFun): m.Result = m() 

    implicit def fromF1[T, A, P <: Product, N <: Nat, H <: HList](f1: (P => T, List[A]))(implicit k: ToArity[P, N], toI: ToInt[N], l: SizedHListAux[A, N, H], toHL: FromTraversable[H], tp: TuplerAux[H, P]) = 
    new SomeFun { 
     type Result = (T, List[A]) 
     def apply(): Result = { 
     val (f, as) = f1 
     val (ts, rest) = (as.take(toI()), as.drop(toI())) 
     f((toHL(ts).get).tupled) -> rest 
     } 
    } 
    // Debug Arity checker 
    def printArity[P <: Product, N <: Nat](p: P)(implicit k: ToArity[P, N], toI: ToInt[N]) = println("Arity: " + toI()) 
} 

object Test { 
    val thedata = List("foo", "bar", "baz", "bob") 
    val tfn = (x: (String, String)) => println("%s and %s".format(x._1, x._2)) 
    def foo = SomeFun.printArity("a" -> "b") 
    //def doit = SomeFun.produce((tfn, thedata)) // Adding this line does not compile 
} 

विचार के साथ खेल रहा हूँ के लिए कोड है कि आप इस मामले में एक समारोह के तर्क arity उपयोग करते हैं, है किसी संबंधित सूची की पार्सिंग को चलाने के लिए उत्पाद प्रकार की धर्मार्थता [ए]। ग्रेफाइट से graphene की परतों को छीलने के लिए चिपचिपा टेप का उपयोग करने की तरह, यानी कार्यों के प्रकार सूची से बाहर खींचें। यह केवल एक निहित प्रकार का उपयोग करके एक स्केच है, लेकिन मुझे लगता है कि इसे सामान्यीकृत किया जा सकता है। महत्वपूर्ण पहलू यह है कि कार्य स्वयं सूची प्रसंस्करण से अनजान हैं।

हालांकि ... अवधारणा को हल करने की कोशिश करते समय अवधारणा विफल होने लगती है [पी, एन] निहित। प्रिंटऑरिटी() द्वारा प्रमाणित के रूप में अपने स्वयं के ToArity पर हल करने योग्य है।

क्या कोई इस बात पर कुछ प्रकाश डाल सकता है कि यह एफ 1 के संदर्भ में क्यों हल नहीं किया जा सकता है? क्या यह सभी निर्भर निहितार्थों को हल नहीं कर सकता है और फिर पहली बार त्रुटि को पंजीकृत कर सकता है, यानी एन एन को ToArity, ToInt और SizedHListAux को संतुष्ट करने के लिए नहीं मिला है?

उत्तर

5

अद्यतन: मैंने अभी आपका संपादन देखा है, जिसका अर्थ है कि आपने पहले पैराग्राफ में पहले बताए गए समस्या को पहले ही संबोधित कर लिया है, लेकिन मुझे उम्मीद है कि बाकी उपयोगी है।

object SizedHListAux { 
    implicit def base[A] = new SizedHListAux[A, _0, HNil] {} 
    implicit def induct[A, H <: HList, N <: Nat, P <: Nat](implicit 
    r: PredAux[N, P], 
    k: SizedHListAux[A, P, H] 
) = new SizedHListAux[A, N, A :: H] {} 
} 

मैं सिर्फ R <: PredAux[N, P] प्रकार पैरामीटर हटा दिया और r टाइप किया है:

scala> implicitly[SizedHListAux[String, _1, String :: HNil]] 
<console>:25: error: could not find implicit value for parameter e... 

सौभाग्य से यह एक आसान ठीक है:

समस्या यह है कि आपके SizedHListAux उदाहरण का पता नहीं लगाया जा रहा है उचित रूप से। मैंने base पर अप्रयुक्त प्रकार पैरामीटर H को भी हटा दिया है, भले ही यह समस्याएं पैदा नहीं कर रहा था-यह कुछ भी नहीं कर रहा था।

है यही कारण है कि लगभग सभी अब सभी fromF1 के लिए उदाहरणों अनुमान लगाया हो:

scala> SomeFun.fromF1((tfn, thedata)) 
res0: SomeFun{type Result = (Unit, List[String])} = [email protected] 

तुम अब भी नहीं SomeFun को (tfn, thedata) के प्रकार से एक दृश्य प्राप्त करने के लिए, हालांकि जा रहे हैं। निम्नलिखित सरल उदाहरण पर विचार करें:

scala> trait Foo 
defined trait Foo 

scala> trait Bar[A, B] 
defined trait Bar 

scala> implicit def toInt[F <: Foo, X](f: F)(implicit ev: Bar[F, X]) = 42 
toInt: [F <: Foo, X](f: F)(implicit ev: Bar[F,X])Int 

scala> implicit object fooBar extends Bar[Foo, String] 
defined module fooBar 

scala> toInt(new Foo {}) 
res0: Int = 42 

scala> implicitly[Foo => Int] 
<console>:12: error: No implicit view available from Foo => Int. 
       implicitly[Foo => Int] 

तो भले ही हम दायरे में एक अंतर्निहित विधि है कि एक Int में एक Foo बदलना होगा, जब यह Foo से Int के लिए एक दृश्य खोजने की कोशिश करता है कि X संकलक के लिए समस्याओं का कारण बनता ।

अपने मामले में मैं SomeFun व्यवसाय छोड़कर और (P => T, List[A]) लेता हूं और (T, List[A]) लौटाकर इस सीमा से बचूंगा।

मैं भी देखेंगे कि ToArity और SizedHListAux दोनों अनावश्यक लगते हैं जब से तुम TuplerAux, LengthAux, और LUBConstraint के साथ एक ही सबूत इकट्ठा कर सकते हैं।

import shapeless._ 

trait SomeFun { 
    type Result 
    def apply(): Result 
} 

implicit def fromF1[T, A, P <: Product, N <: Nat, H <: HList](
    f1: (P => T, List[A]) 
)(implicit 
    tp: TuplerAux[H, P], 
    hl: LengthAux[H, N], 
    toHL: FromTraversable[H], 
    allA: LUBConstraint[H, A], 
    toI: ToInt[N] 
) = new SomeFun { 
    type Result = (T, List[A]) 
    def apply(): Result = { 
    val (f, as) = f1 
    val (ts, rest) = (as.take(toI()), as.drop(toI())) 
    f((toHL(ts).get).tupled) -> rest 
    } 
} 

और फिर:

val tfn = (x: (String, String)) => println("%s and %s".format(x._1, x._2)) 
val thedata = List("foo", "bar", "baz", "bob") 
val sf = fromF1((tfn, thedata)) 

और अंत में: उदाहरण के लिए

scala> sf() 
foo and bar 
res2: (Unit, List[String]) = ((),List(baz, bob)) 

परेशान करने वाला कोई prodN बॉयलरप्लेट आवश्यक।

+0

एएच! अब समझ में आता है, मानक बेकार घटकों का उपयोग करने पर पॉइंटर्स के लिए धन्यवाद ... उम्मीद कर रहा था कि मैं कुछ फन के माध्यम से अलग-अलग उपज() रूपों पर सार के लिए अप्रत्यक्ष हो सकता हूं लेकिन अब यह एक कदम की तरह लगता है। – dconlon

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