2016-04-09 1 views
-2

2つの順序付けられていないマルチセットが等しいかどうかを2回チェックしています。 ...初心者のHaskellのマルチセットの等価性

私はただ一つの関数にそれらを組み合わせたりiEqual内allsort呼び出す方法を知らない

iEqual :: (Eq a) => [a] -> [a] -> Bool 
iEqual [] [] = True 
iEqual (x:xs) (y:ys) = x == y && iEqual xs ys 
iEqual _ _ = False 

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 

と平等のチェック機能:

私はソート機能を持っています

次に、長さをチェックし、xがyのサブセットであるかどうかを確認します。

編集:私はそれを解決しました、ちょうど長さを比較し、そしてそれらがお互いのサブセットであり、それが機能するなら。あなたが任意のリストから、このようなセットを生成するが、それは常に注文の保証することができるようにしたい

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

..

+0

あなたは 'iEqual'を定義する必要はありません。 '[a]'はすでに 'Eq'のインスタンスです。 – chepner

+0

@chepnerこれは、あなた自身の「iEqual」を定義するか、「私たちが授業でやったことを再利用する」ことを含む、運動/宿題/何でもよいかもしれません。 – chi

+0

はいiEqual ::(Eq a)=> [a] - > [a] - > Bool – deathskiller

答えて

5

まず、適切な特殊タイプとして、これらの多重集合を宣言するすべてのいただきありがとうございます。彼らが注文したリストとして同じである場合に限っまあ、

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

(もちろん、あなたもカスタムソート関数を使用できますが、the standard oneは、より効率的になります。)

は今、2つのマルチセットが同じです。 Multisetコンストラクタのリストが常にであることが保証されているので、これは便利です。だから我々はあなた場合は、このEqインスタンスはまた、自動的に生成することができることを

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

(繰り返しますが、あなたもここにiEqual s tを使用することができますが、標準の平等==だけで結構です。)

注意だけで行うことができます書き込み

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 
+0

私はもっと明確にすべきです、私は入力iEqual [4,4,3 ] [3,4,4]と私は彼らが平等であることを示す必要があります(真)。私はiEqual ::(Eq a)=> [a] - > [a] - > Boolを与えられ、そこから続ける必要があります。ライブラリをインポートすることはできません。 – deathskiller

+1

私はあなたが "許されている"ことを気にしません、これはHomeworkOverflowではありません。 - 両方のリストを 'fromList'を使って' Multiset'に変換し、結果を '=='と比較するだけです。あなたが愚かな割り当て制限を満たす必要があると感じたら、 'fromList'を' allSort'と '=='を 'iEqual'に置き換えることができますが、それは愚かです。 – leftaroundabout

2

これは宿題のように見えるので、私はヒントを与えます。

大文字小文字を区別しない方法で文字列を比較したいとします。私たちには2つの機能があります。次のように

lowerString :: String -> String 
lowerString = map toLower 

我々は今、それらを組み合わせることができます:最初の1は、2つの文字列が

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

は、他方が小文字に文字列を変換等しいかどうかをチェックsameStringある

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

(OK、これは大きなヒントです... ;-))