2016-11-13 1 views
3

Je suis (en effet, tout cela est simplifié à partir de mon exemple de travail) en essayant de mapper un HList étiqueté (un enregistrement) de contravariant (retour constant valeur, type d'argument polymorphe) fonctionne sur un enregistrement constitué des types d'arguments appropriés de ces fonctions. Je suis au courant de ZipApply, et cela semble fonctionner pour HLists, mais je veux spécifiquement faire cela indépendamment de l'ordre et utiliser spécifiquement les types de clé pour sélectionner les fonctions à utiliser.Mapper un HList étiqueté (fonctions) de fonctions sur un enregistrement de leurs types d'arguments

Voici mon exemple de code, qui ne compile pour des raisons que je ne peux pas comprendre:

import shapeless._ 
import labelled._ 
import ops.hlist._ 
import ops.record.Selector 
import syntax._ 
import syntax.singleton._ 
import syntax.HListOps 

object POC { 
    case class Foo(bar: String) 
    val gen = LabelledGeneric[Foo] 
    val funs = ('bar ->> { s: String => s.toUpperCase() }) :: HNil 

    val poly = new Poly1 { 
    implicit def apply[K, V] 
    (implicit selector: Selector.Aux[funs.type, K, (V) => String]) = 
     at[FieldType[K, V]] { v => selector(funs)(v) } 
    } 

    def run(foo: Foo)(implicit mapper: Mapper[poly.type, gen.Repr]) = 
    mapper(gen to foo) 

    println(run(Foo("bar"))) 
    // could not find implicit value for parameter mapper: shapeless.ops.hlist.Mapper[POC.<refinement>.type,POC.gen.Repr] 
} 
+0

Quelle version de shapeless utilisez-vous? – laughedelic

+0

@laughedelic 2.3.2 – glittershark

Répondre

2

Le problème ici est que poly n'est pas un identifiant stable, ou il est pas assez stable, ou quelque chose comme ca. Ce qui suit fonctionne très bien:

object poly extends Poly1 { ... } 

Je ne suis pas sûr que je l'ai vu une bien meilleure explication de ce qui se passe ici que le commentaire de Miles sur this answer of mine (qui est maintenant quatre ans et demi ans).

+2

scala est bizarre ... – glittershark

+0

Je pense que Daniel Spiewak a donné une justification juste de ce comportement dans cet exposé: https://vimeo.com/165837504 (environ 28 '). En bref, ces implicits doivent être définis dans un objet compagnon, sinon ils ne sont pas trouvés par le compilateur. –