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

如何为Sum Type中不同位置的Date字段创建统一Lens?

如何为Sum Type中位置不同的字段创建统一Lens?

当然可以创建这样的purchaseDate Lens,核心思路是针对每个构造子分别实现Date的提取(get)和替换(set)逻辑,不管Date在构造子中的位置差异。

手动实现方式

借助Control.Lens中的lens函数,我们可以直接为Fruit类型编写统一的日期操作Lens:

import Control.Lens

data Color = Red | Green deriving (Show)
data Date = Date Int Int Int deriving (Show)
data Fruit = Apple Int Color Date | Banana Color Date deriving (Show)

-- 你已经生成的Prism
makePrisms ''Fruit

purchaseDate :: Lens' Fruit Date
purchaseDate = lens getPurchaseDate setPurchaseDate
  where
    -- 从不同构造子中提取Date
    getPurchaseDate (Apple _ _ date) = date
    getPurchaseDate (Banana _ date) = date
    
    -- 为不同构造子替换Date
    setPurchaseDate (Apple num col _) newDate = Apple num col newDate
    setPurchaseDate (Banana col _) newDate = Banana col newDate

使用示例

定义好Lens后,就可以像操作普通字段一样统一处理所有水果的购买日期:

-- 示例数据
sampleApple = Apple 10 Red (Date 2024 5 20)
sampleBanana = Banana Green (Date 2024 5 21)

-- 获取购买日期
view purchaseDate sampleApple  -- 返回 Date 2024 5 20
view purchaseDate sampleBanana -- 返回 Date 2024 5 21

-- 修改购买日期(比如将日期加1天)
addOneDay (Date y m d) = Date y m (d + 1)
over purchaseDate addOneDay sampleApple  -- 得到 Apple 10 Red (Date 2024 5 21)

关键说明

只要Sum Type的所有构造子都包含目标字段(这里是Date),就可以通过这种方式创建统一Lens。如果存在不含目标字段的构造子,这类Lens就无法定义(因为get操作会有未覆盖的分支),但你的场景中两个构造子都包含Date,所以完全可行。

内容的提问来源于stack exchange,提问作者Shawn Zhang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 12:39:58