2017-08-24 6 views
1

Je peux créer un IndexedTraversal pour les listes avec un indice constant comme ceci:Confusion au sujet COMPOSER objectif indexé

constIndexedList :: i -> Lens.AnIndexedTraversal i [a] [b] a b 
constIndexedList _ _ [] = pure [] 
constIndexedList index f (x:xs) = (:) <$> Lens.indexed f index x <*> constListIndex index f xs 

Je préfère créer en composant deux lentilles plus simple:

constIndex :: i -> Lens.AnIndexedLens i a b a b 
constIndex index f = Lens.indexed f index 

constIndexedList :: i -> Lens.AnIndexedTraversal i [a] [b] a b 
constIndexedList index = Lens.cloneLens (constIndex index) <. traverse 

Cependant, cette ne parvient pas à vérifier le type, et les erreurs de type de lens ne sont pas ceux que je comprends facilement:

• Couldn't match type ‘Lens.Indexed 
         i (t0 a) (Lens.Bazaar (Lens.Indexed i) a b (t0 b))’ 
       with ‘[a] -> Lens.Bazaar (Lens.Indexed i) a b [b]’ 
    Expected type: Lens.Indexed 
        i (t0 a) (Lens.Bazaar (Lens.Indexed i) a b (t0 b)) 
       -> [a] -> Lens.Bazaar (Lens.Indexed i) a b [b] 
    Actual type: ([a] -> Lens.Bazaar (Lens.Indexed i) a b [b]) 
       -> [a] -> Lens.Bazaar (Lens.Indexed i) a b [b] 
• In the first argument of ‘(<.)’, namely 
    ‘Lens.cloneLens (constIndex index)’ 
    In the expression: Lens.cloneLens (constIndex index) <. traverse 

Pourquoi est-ce que je ne peux pas composer l'objectif indexé comme ça?

J'ai fini par trouver une façon modulaire différente de le faire (Lens.reindexed (const index) Lens.traversed, mais je me demande encore pourquoi la méthode mentionnée ci-dessus ne fonctionne pas ..

Répondre

2

(<.) une optique indexée attend sur sa gauche, mais lui donne cloneLens une lentille non indexée.

un correctif partiel est d'utiliser Lens.cloneIndexedLens au lieu de cloneLens.

Cependant, A_/An_ variantes de l'optique (AnIndexedLens) sont destinés à être l'argument types, pas les types de résultats, qui peuvent utiliser des optiques régulières (IndexedLens). Avec cela, cloneIndexedLens devient inutile.

constIndex :: i -> Lens.IndexedLens i a b a b 
constIndex i f = Lens.indexed f i 

constIndexedList :: i -> Lens.IndexedTraversal i [a] [b] a b 
constIndexedList i = constIndex i <. traverse 

entrées et sorties monomorphes polymorphes améliorer composabilité.

IndexedLens est un type polymorphe (notez le mot-clé forall dans la définition de type).

type IndexedLens i s t a b = forall f p. (Indexable i p, Functor f) => p a (f b) -> s -> f t 

AnIndexedLens est monomorphe.

type AnIndexedLens i s t a b = Optical (Indexed i) (->) (Pretext (Indexed i) a b) s t a b 

Chaque IndexedLens est AnIndexedLens, mais la conversion dans l'autre sens doit passer par un cloneIndexedLens explicite.