【发布时间】:2018-03-05 12:45:13
【问题描述】:
假设我有一个列表[A]。如果满足某些谓词,我想更新列表的特定元素。但如果没有这样的元素,我想先将元素添加到列表中。我目前的解决方案是手动编写函数,如果不存在将元素插入列表,然后使用filtered Traversal 更新我的元素。像这样:
-- 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 l@(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
我想知道是否有更好(更短、更惯用)的解决方案?如果可能的话,我将不胜感激仅使用 microlens 系列软件包的解决方案。
【问题讨论】:
-
@chepner 非常接近但不完全一致。如您所见,我使用的是列表,因此效率不是我的首要任务。虽然我认为我的解决方案已经足够高效,甚至可能只使用一次遍历列表。我想要更短的形式(没有大的效率损失)。而且我对使用镜片的解决方案很感兴趣(因为没有镜片我可以自己做)。不同之处在于,在您的表单中
myUpdate应该检查是否修改元素,而在我的表单中map myUpdate将更改列表中的每个元素。但是你的想法和我想要的很接近。 -
哦,对不起。我知道你真正想要什么,然后忘了删除我的评论。
标签: list haskell haskell-lens