初学者Haskell multiset相等

时间:2016-04-09 20:06:13

标签: haskell

我正在创建一个函数,检查两个无序多重集是否相等。

我有一个排序功能:

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的子集。

编辑:我解决了它,只是比较了长度,然后如果它们是彼此的子集并且它有效。谢谢大家..

2 个答案:

答案 0 :(得分:5)

首先,将这些多重集声明为适当的不同类型:

newtype Multiset a = Multiset { getOrderedList :: [a] }

您希望能够从任何列表生成此类集,但保证始终排序。那么,

fromList :: Ord a => [a] -> Multiset a
fromList = Multiset . sort

(当然您也可以使用自定义排序功能,但the standard one会更有效率。)

现在,如果它们与有序列表相等,则两个多字节相等。这是一致的,因为我们确保Multiset构造函数中的列表始终是!所以我们可以做到

instance  (Eq a) => Eq (Multiset a) where
  Multiset s == Multiset t = s == t

(同样,您也可以在这里使用iEqual s t,但标准等式==就可以了。)

请注意,如果您只是编写

,也可以自动生成此Eq实例
newtype Multiset a = Multiset { getOrderedList :: [a] }
      deriving (Eq)

(您还可以推导出其他有用的课程,我建议ShowGenericFunctor。)

Prelude> newtype Multiset a = Multiset { getOrderedList :: [a] } deriving (Eq)
Prelude> :m +Data.List
Prelude Data.List> let fromList = Multiset . sort
Prelude Data.List> fromList [4,4,3] == fromList [3,4,4]
True
Prelude Data.List> fromList [4,4,3] == fromList [3,4,5]
False

答案 1 :(得分:2)

由于这看起来像是作业,我只会给出一个提示。

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

sameString :: String -> String -> Bool
sameString = (==)

另一个将字符串转换为小写:

lowerString :: String -> String
lowerString = map toLower

我们现在可以将它们组合如下:

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

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