Haskell中union函数下的闭包

of1yzvn4  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(140)

所以我试着做了一个函数,它接受一个列表的集合,并返回true,这个集合是否在union下关闭。

closureUnderUnion :: [[String]] -> Bool
closureUnderUnion mp =
  all (\i -> all (\j -> union i j `elem` mp) mp) mp

但对于

closureUnderUnion [[],["a","b","c"],["a"],["b", "c"]]

返回False

jgwigjjp

jgwigjjp1#

问题是union不能保证返回一个有序列表:

ghci> union ["b"] ["a"]
["b","a"]

所以你需要使用一种不同的等式:

newtype SetList a = SetList [a]

instance Eq a => Eq (SetList a) where
  SetList xs == SetList ys = 
     all (`elem` ys) xs && all (`elem` xs) ys

closureUnderUnion :: [[String]] -> Bool
closureUnderUnion mp =
  all (\i -> all (\j -> SetList (union i j) `elem` map SetList mp) mp) mp

如果你的元素确实有一个Ord示例,就像你的例子中的[String]一样,那么最好的解决方案是使用一个针对集合操作优化的数据结构:

import qualified Data.Set as Set
import Data.Set (Set)

closureUnderUnion :: Set (Set String) -> Bool
closureUnderUnion mp =
  all (\i -> all (\j -> Set.union i j `Set.member` mp) mp) mp

相关问题