You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Lenses条件设置嵌套记录与列表值并实现ensureRecAFlag函数?

使用Lenses实现ensureRecAFlag函数的方案

实现思路

按照需求优先级依次处理:

  1. 先检查RecB的RecA列表中是否存在recaFlag=True的元素,若存在直接返回原对象;
  2. 若不存在符合条件的元素,优先查找recaName="internal_code"的RecA,找到则将其recaFlag设为True;
  3. 若没有internal_code的RecA,再查找recaName="id"的RecA,找到则将其recaFlag设为True;
  4. 上述情况都不满足时,不做任何修改。

完整代码实现

import Control.Lens
import Data.Text (Text)
import Data.Maybe (isJust)

ensureRecAFlag :: RecB -> RecB
ensureRecAFlag b
  -- 规则1:存在recaFlag=True的RecA,直接返回原对象
  | any (view flag) (b ^. recAList) = b
  -- 规则2:修改name为"internal_code"的RecA的flag
  | isJust (preview (recAList . traversed . filtered ((== "internal_code") . view name)) b) =
      b & recAList . traversed . filtered ((== "internal_code") . view name) . flag .~ True
  -- 规则3:修改name为"id"的RecA的flag
  | isJust (preview (recAList . traversed . filtered ((== "id") . view name)) b) =
      b & recAList . traversed . filtered ((== "id") . view name) . flag .~ True
  -- 规则4:其他情况不操作
  | otherwise = b

-- 原数据定义(保持不变)
data RecA = RecA
  { recaName :: !Text
  , recaValue :: !Int
  , recaFlag :: !Bool
  }
$(makeLensesWith abbreviatedFields ''RecA)

data RecB = RecB
  { recbName :: !Text
  , recbRecAList :: ![RecA]
  }
$(makeLensesWith abbreviatedFields ''RecB)

代码解释

  • 规则1:通过view flag提取RecA的flag字段,用any检查列表中是否存在True值;
  • 规则2、3:用preview检查是否存在符合name条件的RecA,若存在则通过&运算符结合lens修改对应元素的flag。其中traversed用于遍历列表中的每个RecA,filtered筛选出符合name条件的元素,最后通过flag .~ True设置flag值;
  • 所有lens由makeLensesWith abbreviatedFields自动生成,比如RecA的recaFlag对应flag lens,RecB的recbRecAList对应recAList lens。

内容的提问来源于stack exchange,提问作者Saurabh Nanda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 06:30:31