Data.Set.deleteFindMin用于集合的集合的等效函数技术问询
解决Haskell中集合嵌套集合的类型不匹配问题
首先,咱们先拆解一下你遇到的错误:
Couldn't match type
Set.Set String' with[t0]' Expected type: Set.Set [t0] Actual type: Set.Set (Set.Set String)
这个错误的核心是:你的代码里有某个部分期望处理元素为列表的集合(Set [t0]),但你实际传入的是元素为字符串集合的集合(Set (Set String))——说白了就是把Set String和列表[t0]搞混了,大概率是误用了列表的操作函数(比如head、tail)来处理Set类型。
正确实现你要的「取出首个集合」功能
你需要的类似deleteFindMin的功能,其实Data.Set本身就支持:因为Set (Set String)满足Ord约束(String是Ord,Set的实例要求元素必须Ord),所以直接用Set.deleteFindMin就能完美实现需求——它的返回值正好是(取出的集合, 剩余集合的集合)。
先给你一个极简的实现示例:
import qualified Data.Set as Set -- 你的类型定义 type SofSes = Set.Set (Set.Set String) -- 实现取出首个集合的函数 takeFirstSofSes :: SofSes -> (Set.Set String, SofSes) takeFirstSofSes = Set.deleteFindMin
调用这个函数时,比如takeFirstSofSes mySofSes,就能直接得到你要的(取出的Set String,剩下的SofSes)。
分析你现有代码的问题
看你给出的代码片段reduce ts | (Set.null (setW ts))==False = do reduce (firstFor...,可能的问题点有这些:
setW函数的返回类型错误:如果setW ts返回的是Set [String](元素为列表的集合),而不是你定义的SofSes,就会触发类型不匹配。- 误用列表操作处理Set:比如你在
firstFor函数里,可能用了head . Set.toList这类把Set转成列表后取首的操作,后续又把这个结果当成列表来用——但实际上这个结果是Set String,不是列表。 - 不必要的
do关键字:如果reduce是纯函数(不是IO或其他Monad类型),用do会引入额外的类型约束,反而可能导致类型混乱,直接写纯逻辑就行。
修正reduce函数的示例
假设你的reduce是纯递归函数,修正后的逻辑大概是这样:
reduce :: SofSes -> [Set.Set String] -- 假设最终返回取出的所有集合的列表,你可以改成你的实际返回类型 reduce ts | Set.null ts = [] -- 处理空集合的终止条件 | otherwise = let (firstSet, remainingSets) = Set.deleteFindMin ts in firstSet : reduce remainingSets
内容的提问来源于stack exchange,提问作者user7303261
相关产品推荐
相关产品推荐

