2

Supposons une classe externe avec un composite interne de deux classes internes:usines dépendant du chemin parcouru avec instance enfermant implicite, dans Scala

class Outer(val times: Int) { 

    class Inner(val count: Int) 
    object Inner { 
    def apply(i: Int) = new Inner(i) 
    } 

    class InnerWrap(val i: Inner) 
    object InnerWrap { 
    def apply(i: Inner) = new InnerWrap(i) 
    } 
    def method(i: Inner) = i.count * times 
} 
object Outer { 
    def apply(times: Int) = new Outer(times) 
} 

class PathDependentExpl { 
    val o = new Outer(3) 
    val i = o.Inner(2) 
    val p = new Outer(5) 
    val j = p.Inner(3) 
    println(o.method(i)) 
    println(p.method(j)) 
} 

bien beau. Nous avons même une protection de compilateur contre l'alimentation des inners d'un Outer aux méthodes d'un autre Outer par des types dépendant du chemin.

Mais la syntaxe est un peu ennuyante. Je veux être en mesure d'écrire quelque chose comme

implicit val p = new Outer(5) 
val k = Inner(3) // same as p.Inner(3) 
val l = InnerWrap(Inner(3)) 

... omettre l'instance externe pour le bloc où l'implicite est valide. J'ai donc ajouté des méthodes déléguées avec l'objet Outer en tant que paramètre implicite.

object Outer { 
    def apply(times: Int) = new Outer(times) 
    def Inner(c: Int)(implicit o: Outer) = o.Inner(c) 
    def InnerWrap(i: o.Inner)(implicit o: Outer) = o.InnerWrap(i) 
} 

Cette dernière InnerWrap donne de définition: « type de méthode dépendante illégale: paramètre apparaît dans le type d'un autre paramètre dans la même section ou une précédente », ce qui fait réellement sens. J'ai essayé def InnerWrap[O <: Outer#Inner](i: O)(implicit o: Outer) = o.InnerWrap(i) et d'autres variantes en vain.

La question est, comment puis-je toujours utiliser la syntaxe du nettoyeur? Comment la déclaration de InnerWrap dans l'objet Outer peut être faite pour accepter o.Inner s ou équivalent?

+1

Ce n'est pas exactement ce que vous voulez, mais vous pouvez importer l'objet 'Inner' de' p', c'est-à-dire 'val p = new Outer (5); importer p.Inner; val j = Inner.apply (3) '. –

+0

C'est sûr! Cela rend les méthodes déléguées inutiles et nettoie la syntaxe. Postez-le comme une réponse afin que je puisse l'accepter, si vous voulez. – vlfig

Répondre

2

Comme je l'ai mentionné dans un commentaire ci-dessus, il est possible d'importer les objets (ou méthodes) vous avez besoin p, qui peut vous donner la syntaxe propre que vous cherchez:

scala> val p = new Outer(5) 
p: Outer = [email protected] 

scala> import p._ 
import p._ 

scala> val k = Inner(3) 
k: p.Inner = [email protected] 

scala> val l = InnerWrap(Inner(3)) 
l: p.InnerWrap = [email protected] 
Questions connexes