初学者Haskell多集等式
我正在做一个函数2,检查两个无序的多重集是否相等 我有一个排序功能:初学者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
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)