2016-05-17 12 views
1

Hier mein Anwendungsfall ist:In einen Typ Parameter, aber nicht den anderen?

def mkWrapper[A,B](doer: StuffDoer[B])(implicit ev: A => B) = 
    new StuffDoer[A] { 
     override def doStuff(a: A) = doer.doStuff(ev(a)) 
    } 

Nun nehme ich an eine Instanz von

StuffDoer[AwfullyLong[Complicated,And],_ <: Difficult[ToRead],Type]

definiert irgendwo, und eine implizite Konvertierung von String ... na ja, dass haben Art.

Ich bin auf der Suche nach Vorschlägen, wie ich mkWrapper[String,_](doer) aufrufen kann, und habe es seinen zweiten Typ Parameter aus dem Typ doer abzuleiten, anstatt es zu buchstabieren.

Ideen? spezifizieren und

  • eine apply Methode mit dem Rest der Parameter des Typs

  • +2

    Dies kann oder kann nicht helfen: https://tpolecat.github.io/2015/07/30/infer.html –

    Antwort

    2

    Die allgemeine Lösung für dieses Problem ist es, eine neue Klasse mit

    • dem Typparameter Sie nicht möchten, erstellen.

    Einige Beispiele in cats (Coproduct.left[X]) und shapeless (die *Aux Syntax Hilfsklassen).

    In Ihrem Fall könnte dies wie folgt aussehen:

    class WrapperHelper[A] { 
        def apply[B](doer: StuffDoer[B])(implicit ev: A => B) = 
        new StuffDoer[A] { 
         override def doStuff(a: A) = doer.doStuff(ev(a)) 
        } 
    } 
    
    def mkWrapper[A] = new WrapperHelper[A] 
    

    Sie am Ende mit etwas, das wie ein Funktionsaufruf aussieht, wenn es tatsächlich zwei sind:

    val stuff: StuffDoer[Int] = ??? 
    mkWrapper[Double](stuff) 
    mkWrapper[Double].apply(stuff) 
    

    Dies ist der gleiche Trick Rob Norris erklärt auf der Seite @mz in seinem Kommentar verlinkt.

    +0

    Vielen Dank! Das funktioniert fast, bis auf eine Komplikation, die ich im Originalpost nicht erwähnt habe: Die 'mkWrapper'-Signatur sieht tatsächlich wie 'mkWrapper [A: Manifest, B]' aus, also muss ich das' Manifest'-Ding tragen, und jetzt, wenn ich 'mkWrapper [Double] (stuff)' schreibe, will es 'stuff'' Manifest' sein :(Ich kann 'mkWrapper [Double] .apply (stuff) 'schreiben, was immer noch eine Verbesserung ist, aber der Perfektionist in Ich bin nicht glücklich :( Irgendwelche Ideen, wie man das umgehen kann? – Dima

    +0

    @Dima Es scheint, dass Sie in diesem Fall ein zusätzliches implizites 'man: Manifest [A]' zur 'apply' Funktion hinzufügen könnten (und entfernen Sie' : Manifest-Kontext gebunden an 'mkWrapper', aber es ist nicht immer möglich, die impliziten Parameter zu verschieben. –

    Verwandte Themen