2017-09-27 2 views
1

Je crée un wrapper pour Shaleless HList et j'aimerais utiliser la fonction updatedAt pour mettre à jour une valeur dans le HList, mais je n'arrive pas à obtenir les implicits correctement. Ce sont les deux versions que je pense sont les plus proches d'une solution de travail:use ReplaceAt dans une classe

class Data[L <: HList](val hl: L) { 

    def updatedAtV1[V](n : Nat, value : V)(implicit 
     replacer : ReplaceAt[L, n.N, V]) : replacer.Out = replacer(hl, value) 

    def updatedAtV2[V, Out <: HList](n : Nat, value : V)(implicit 
     replacer : ReplaceAt.Aux[L, n.N, V, (V, Out)]) : Out = replacer(hl, value)._2 

} 

V1 compiles, mais parce qu'il renvoie une Tuple je suis incapable de le forcer à un type Tuple donc je ne peux pas l'élément replacer(hl, value)._2. Dans V2 le compilateur ne peut pas résoudre le type Out.

Notez que V2 fonctionne correctement, si la valeur est le même type du type qu'il remplace, mais échoue si c'est un type différent.

Répondre

2

Il ne fonctionne pas avec le type différent à cause de cette implicite:

ReplaceAt.Aux[L, n.N, V, (V, Out)] 

Vous dites que vous voulez placer une valeur de type V à n, et obtenir V retour sur HList. Vous pouvez y remédier en introduisant le paramètre de type supplémentaire:

def updatedAtV3[V, W, Out <: HList](n : Nat, value : V)(implicit 
    replacer : ReplaceAt.Aux[L, n.N, V, (W, Out)]) : Out = replacer(hl, value)._2 

Il W - un élément déjà dans la liste - peut être quelque chose (il sera déduit du paramètre implicite), de sorte que tout fonctionne:

new Data(1 :: HNil).updatedAtV3(0, 42) == 42 :: HNil  
new Data(1 :: HNil).updatedAtV3(0, "foo") == "foo" :: HNil 
+0

Je vous remercie. J'ai complètement raté ce petit bout. – jamborta