2017-03-05 1 views
1

Dire que j'ai une classe qui prend un type plus kinded, et je suis en train d'écrire quelque chose comme ceci:extraire et utiliser les paramètres de type dans les types les plus élevés?

class Foo[T[U]](thing: T[U]) { 
    def someMethodThatUsesU(arg: U): U = ??? 
} 

Cela ne peut pas compiler, car le compilateur ne reconnaît pas le symbole U. Comment venir? Existe-t-il un autre moyen d'écrire ceci sans faire quelque chose comme class Foo[U, T[U]]?

Quelque contexte: ceci est un exemple simplifié du problème. En fin de compte, je voudrais écrire quelque chose comme ceci:

trait SomeTrait[T] 

class SomeClass[T[U] <: SomeTrait[U]](arg: T[U]) { 
    def somethingWithU(arg: U): U = ??? 
} 

Répondre

0

J'ai découvert une solution qui fonctionne pour mon cas d'utilisation très bien. Il suffit d'affecter ce type à un membre de type et d'utiliser la projection de type:

trait SomeTrait[T] { 
    type A = T 
} 

class SomeClass[T <: SomeTrait[_]] { 
    def someMethod(arg: T#A): T#A 
} 
3

T[U] est pas vraiment un type plus élevé kinded si vous aimez ce que U est. C'est juste un type ancien. Un type plus élevé serait si votre classe ou méthode a été paramétrée par le seul constructeur de type de quelque chose, par ex. Option ou List.

class[T[U]](...) Echec de la compilation car vous essayez d'utiliser deux paramètres de type, mais seulement déclarer T. Il n'y a aucun moyen de déclarer deux paramètres de type de cette manière. La seule bonne option que vous avez est de déclarer T être plus élevé kinded, avec un second paramètre de type U qui varie indépendamment:

class Foo[T[_], U](thing: T[U]) { 
    def someMethodThatUsesU(arg: U): U = ??? 
} 
+0

Ah, merci de préciser ce que sont les types plus élevés. Oui, cela fonctionnerait, bien que ce soit essentiellement ce que j'essayais d'éviter à l'origine :( – bioball