初学者Haskell多集等式

初学者Haskell多集等式,haskell,Haskell,我正在做一个函数2,检查两个无序的多重集是否相等 我有一个排序功能: allsort :: (Ord a) => [a] -> [a] allsort [] = [] allsort (x:xs) = let smallerSorted = allsort [a | a <- xs, a <= x] biggerSorted = allsort [a | a <- xs, a > x] in smalle

我正在做一个函数2,检查两个无序的多重集是否相等

我有一个排序功能:

allsort :: (Ord a) => [a] -> [a]  
allsort [] = []  
allsort (x:xs) =   
    let smallerSorted = allsort [a | a <- xs, a <= x]  
        biggerSorted = allsort [a | a <- xs, a > x]  
    in  smallerSorted ++ [x] ++ biggerSorted  
iEqual :: (Eq a) => [a] -> [a] -> Bool
iEqual [] [] = True 
iEqual (x:xs) (y:ys) = x == y && iEqual xs ys
iEqual _ _ = False
我只是不知道如何将它们组合成一个函数或调用iEqual中的allsort

然后另一个想法是检查长度,如果x是y的子集


编辑:我解决了它,只是比较了长度,然后如果它们是彼此的子集,它就工作了。谢谢大家。

首先,将这些多集声明为正确的不同类型:

newtype Multiset a = Multiset { getOrderedList :: [a] }
您希望能够从任何列表生成这样的集合,但要保证它总是有序的。那么

fromList :: Ord a => [a] -> Multiset a
fromList = Multiset . sort
(当然,您也可以使用自定义排序功能,但这样会更有效率。)

现在,两个多重集相等,如果它们作为有序列表相等。这很方便,因为我们已经确保
Multiset
构造函数中的列表总是有序的!这样我们就可以做了

instance  (Eq a) => Eq (Multiset a) where
  Multiset s == Multiset t = s == t
(同样,您也可以在这里使用
iEqual st
,但是标准的等式
=
很好。)

请注意,如果您只需编写,也可以自动生成此
Eq
实例

newtype Multiset a = Multiset { getOrderedList :: [a] }
      deriving (Eq)
(您还可以派生其他有用的类,我建议
Show
Generic
Functor


既然这看起来是家庭作业,我就给你一个提示

假设我们想要以不区分大小写的方式比较字符串。我们有两个功能。第一个是
sameString
,它检查两个字符串是否相等

sameString :: String -> String -> Bool
sameString = (==)
另一个将字符串转换为小写:

lowerString :: String -> String
lowerString = map toLower
我们现在可以将它们组合如下:

caseInsensitiveMatch :: String -> String -> Bool
caseInsensitiveMatch s1 s2 = sameString (lowerString s1) (lowerString s2)

(好的,这是一个很大的提示…;-)

我应该说得更清楚,我得到了一个相等的输入[4,4,3][3,4,4],我需要证明它们是相等的(真的)。我得到了equal::(Eq a)=>[a]->[a]->[a]->Bool,我必须从那里继续。我不允许导入库。我不在乎“允许”你做什么,这不是HomeworkOverflow只需使用
fromList
将两个列表转换为
多集
,并将结果与
=
进行比较。如果你觉得需要满足一些愚蠢的分配限制,你可以用
allSort
替换
fromList
,用
iEqual
替换
=
,但这很愚蠢。你不需要定义
iEqual
[a]
已经是
Eq
@chepner的一个实例,我想这可能是一个练习/家庭作业/任何包括“定义你自己的
iEqual
”或“重用我们在课堂上所做的”。是的,我们只需要完成给定iEqual的函数::(Eq a)=>[a]->[a]->[a]->Bool
caseInsensitiveMatch :: String -> String -> Bool
caseInsensitiveMatch s1 s2 = sameString (lowerString s1) (lowerString s2)