2017-07-26 5 views
6

Imaginez que j'ai la liste suivante:Appliquer deux plis ou accesseurs et seulement réussir lorsque les deux réussir

lst :: [(Bool, Maybe Integer)] 
lst = [(True, Just 3), (True, Nothing), (False, Just 12)] 

Utilisation de la bibliothèque de l'objectif, je veux extraire les éléments des tuples, mais je veux seulement qu'il réussisse lorsque le deuxième élément est Just. Je veux une certaine optique, split qui fonctionne comme ceci:

> lst ^.. folded.split (_1.to not) (_2._Just) 
[(False, 3), (True, 12)] 

Je peux mettre en œuvre split moi-même comme ceci:

split :: Getting (First a) s a -> Getting (First b) s b -> Fold s (a, b) 
split a b = folding (\x -> (,) <$> (x ^? a) <*> (x ^? b)) 

... qui semble fonctionner. Cependant, il semble que je doive réinventer la roue. Y at-il quelque chose déjà fourni par la bibliothèque de lentilles qui accomplit cela d'une manière tout aussi agréable?

Répondre

6

Le aside combinateur prend une Prism qui fonctionne sur le second composant d'un tuple et retourne un Prism qui fonctionne sur l'ensemble tuple:

ghci> lst ^.. folded.aside _Just 
[(True,3),(False,12)] 

Les résultats de prisme résultant lorsque est mis en correspondance le composant, sinon il échoue .

La combinaison avec to et bimap, nous pouvons reproduire votre exemple:

ghci> lst ^.. folded.aside _Just.to (bimap not id) 
[(False,3),(True,12)] 

Pour travailler sur le premier composant, nous pouvons utiliser swapped:

ghci> [(Just 3,False)]^..folded.swapped.aside _Just.swapped 
[(3,False)]