2016-03-01 2 views
1

suppose que j'ai une fonction qui extrait une valeur interne en utilisant une autre valeur intérieure à partir d'une valeur externeCompose lentilles à l'accès de type externe pendant getter et setter

func :: outer -> inner1 -> inner2 

Ensuite, j'ai une fonction qui cretes une lentille entre la valeur externe et une autre valeur en utilisant cette valeur inner2

existingLensFunc :: inner2 -> Lens' outer result 

Est-il possible de créer une autre fonction qui crée une lentille betwee valeur extérieure et de la valeur de résultat en utilisant la valeur inner1?

finalLens :: inner1 -> Lens' outer result 

En d'autres termes, existe-t-il un meilleur moyen d'écrire ceci?

finalLens inner1 = lens getter setter 
    where setter outer result = let inner2 = func outer inner1 in set (existingLens inner2) result outer 
     getter outer = let inner2 = func outer inner1 in view (existingLens inner2) outer 

Répondre

5

Voyons unshorten les types ...

existingLensFunc 
    :: Inner2 -> (∀ f . Functor f => (Result -> f Result) -> Outer -> f Outer) 
    ≡ ∀ f . Functor f => Inner2 -> (Result -> f Result) -> Outer -> f Outer 

finalLens 
    :: ∀ f . Functor f => Inner1 -> (Result -> f Result) -> Outer -> f Outer 

Il y a un endroit évident pour “ saisir au large ” un Outer ici: le dernier argument.

finalLens inner1 fres outer = existingLensFunc (func outer inner1) fres outer