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

Haskell中newtype嵌套结构下Literal过滤函数实现问题

Haskell合取范式Literal过滤函数实现方案

问题分析

你定义的And、Or都是newtype包装的容器,直接用map会触发类型不匹配错误——map作用于列表,而And x是包装了[Or x]的新类型,不能直接当作列表操作。另外你的代码存在拼写错误:Lit应为Literal,且未处理Negation构造器,也没把过滤后的结果重新包装回Or和And类型。

实现思路

  1. 拆包与打包:newtype本质是零开销包装,需要先把And拆成内部的[Or x],处理完再重新包成And;同理Or也要拆成[Literal x],过滤后再包回Or。
  2. 覆盖所有Literal构造器:过滤逻辑要同时处理Literal x和Negation x,根据实际需求决定是否保留。

代码实现

假设condition是判断x是否满足条件的函数(类型为x -> Bool),可以这样实现:

data Literal x = Literal x | Negation x
  deriving (Show, Eq)

newtype Or x = Or [Literal x]
  deriving (Show, Eq)

newtype And x = And [Or x]
  deriving (Show, Eq)

-- 过滤单个Or结构中的Literal
filterOr :: (x -> Bool) -> Or x -> Or x
filterOr cond (Or literals) = Or $ filter keepLiteral literals
  where
    keepLiteral (Literal x) = cond x
    keepLiteral (Negation x) = cond x  -- 可按需修改,比如只保留非否定Literal就设为False

-- 过滤整个And结构中的Literal
filterLit :: (x -> Bool) -> And x -> And x
filterLit cond (And ors) = And $ map (filterOr cond) ors

关键细节说明

  • newtype的拆包与打包:通过模式匹配(And ors)取出内部的[Or x],处理完成后用And构造器重新包装,这是newtype操作的核心要求。
  • 完整处理Literal分支:keepLiteral函数匹配了Literal和Negation两个构造器,你可以根据业务需求调整逻辑,比如仅保留非否定的Literal,就把Negation分支的返回值改为False。
  • 严格保持类型一致性:每个处理函数的输入输出都严格对应自定义的新类型,避免类型不匹配错误。比如filterOr输入Or x输出Or x,filterLit输入And x输出And x。

测试示例

定义判断是否等于1的条件函数,测试过滤效果:

testAnd :: And Int
testAnd = And [Or [Literal 1, Negation 2], Or [Literal 3, Negation 1]]

main = print $ filterLit (==1) testAnd
-- 输出:And [Or [Literal 1], Or [Negation 1]]

内容的提问来源于stack exchange,提问作者K D

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:30:57