gpt4 book ai didi

list - 如果列表的元素符合某些条件,则更改列表元素,如果不符合,则使用 Data.Lens 添加新元素

转载 作者:行者123 更新时间:2023-12-04 08:10:51 24 4
gpt4 key购买 nike

我有一个记录列表,需要一个函数来搜索列表以查找具有给定名称的记录并修改此记录的值,或者如果没有记录匹配,则将新记录附加到结果列表中。到目前为止,这是我的代码:

import Control.Lens
import Control.Applicative ((<$>), pure)
import Data.List (any)

data SomeRec = SomeRec { _name :: String, _val :: Int }
$(makeLenses ''SomeRec)

_find :: (a -> Bool) -> Simple Traversal [a] a
_find _ _ [] = pure []
_find pred f (a:as) = if pred a
then (: as) <$> f a
else (a:) <$> (_find pred f as)

changeOrCreate :: [SomeRec] -> String -> (Int -> Int) -> [SomeRec]
changeOrCreate recs nameToSearch valModifier =
if (any (\r -> r^.name == nameToSearch) recs)
then over (_find (\r -> r^.name == nameToSearch)) (over val valModifier) recs
else recs ++ [SomeRec nameToSearch (valModifier 0)]

它工作正常,但我想知道是否有更直接的方法来使用 Data.Lens (没有 if -构造)?另外,我必须写 _find吗?函数还是库中有等效的东西?

更新:这里是实验来源的要点: https://gist.github.com/SKoschnicke/5795863

最佳答案

怎么样:

changeOrCreate :: String -> (Int -> Int) -> [SomeRec] -> [SomeRec]
changeOrCreate nameToSearch valModifier =
pos . val %~ valModifier
& outside (filtered (not . has pos)) %~ (. newRec)
where
pos :: Traversal' [SomeRec] SomeRec
pos = taking 1 (traversed . filtered (anyOf name (== nameToSearch)))
newRec = (SomeRec nameToSearch 0 :)

关于list - 如果列表的元素符合某些条件,则更改列表元素,如果不符合,则使用 Data.Lens 添加新元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17087663/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com