Disons que j'ai une liste [A]
. Je veux mettre à jour un élément spécifique de la liste s'il satisfait un prédicat. Mais s'il n'y a pas un tel élément, je veux ajouter un élément à la liste en premier. Ma solution actuelle consiste à écrire manuellement la fonction pour insérer un élément dans la liste si ce n'est pas le cas, puis utiliser filtered
Traversal pour mettre à jour mon élément. Comme ceci:Comment ajouter un élément à la liste s'il n'y a pas de 'lentille'?
-- inserts element to list if there's no a single element
-- which satisfies given predicate
insertIfNot :: (a -> Bool) -> a -> [a] -> [a]
insertIfNot _ e [] = [e]
insertIfNot p e [email protected](x:xs) = if p x then l else x : insertIfNot p e xs
functionIWantToWrite :: [A] -> [A]
functionIWantToWrite = modifyItem . addEmptyItem
where
addEmptyItem = insertIfNot myPredicate item
modifyItem = each.filtered myPredicate %~ myUpdate
Je me demande s'il y a une meilleure solution (plus courte, plus idiomatique)? Si possible, j'apprécierais la solution qui utilise seulement la famille de paquets microlens
.
@chepner très proche mais pas exactement. Comme vous pouvez le voir, j'utilise des listes, donc l'efficacité n'est pas la priorité absolue pour moi. Bien que je pense que ma solution est déjà assez efficace et utilise probablement même une seule traversée de liste. Je veux une forme plus courte (sans grosse perte d'efficacité). Et je suis intéressé par une solution qui utilise des lentilles (parce que w/o lentilles je peux le faire moi-même). La différence est que dans votre formulaire 'myUpdate' devrait vérifier s'il faut modifier l'élément alors que dans ma forme' map myUpdate' va changer tous les éléments de la liste. Mais ton idée est très proche de ce que je veux. – Shersh
Oh, désolé. J'ai compris ce que vous vouliez vraiment, puis j'ai oublié de supprimer mon commentaire. – chepner