Set aは、型aの一意な値の並びです。
値はcomparable型である必要があります(Int、Float、Time、Char、String、およびcomparable型のタプルやリスト)。
Set.toListとSet.fromListを使うと、リストと集合を相互に変換できます。
Setの内部構造のため、Set.fromListから得られるリストはソートされていることが保証されています。
Set.fromList [2, 3, 3, 3, 1, 1, 2]
--> Set.fromList [1, 2, 3]
Set.toList (Set.fromList [2, 3, 3, 3, 1, 1, 2])
--> [1, 2, 3]
Set.empty、Set.singleton、Set.insert、Set.removeを使うと、集合を作成して要素を追加できます。
Set.empty
--> Set.fromList []
Set.singleton "hi"
--> Set.fromList ["hi"]
eightyEight = Set.singleton 88
Set.insert 88 eightyEight
--> Set.fromList [88]
Set.insert 89 eightyEight
--> Set.fromList [88, 89]
Set.remove 88 eightyEight
--> Set.fromList []
Set.remove 89 eightyEight
--> Set.fromList [88]
Set.member、Set.isEmpty、Set.sizeという関数を使うと、集合の中身を調べられます。
Set.member 88 eightyEight
--> True
Set.isEmpty eightyEight
--> False
Set.size eightyEight
--> 1
集合はSet.union、Set.intersect、Set.diffで組み合わせることができます。
a = Set.fromList [1, 10, 100]
b = Set.fromList [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Set.union a b
--> Set.fromList [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100]
Set.intersect a b
--> Set.fromList [1, 10]
Set.diff a b
--> Set.fromList [100]
Set.diff b a
--> Set.fromList [2, 3, 4, 5, 6, 7, 8, 9]
集合を絞り込んだり、分割したりすることもできます。
even n = modBy 2 n == 0
Set.filter even b
--> Set.fromList [2, 4, 6, 8, 10]
Set.partition even b
--> (Set.fromList [2, 4, 6, 8, 10], Set.fromList [1, 3, 5, 7, 9])
Blorkemon™️のカードへの懐かしさはとどまるところを知らず、また集め始めてしまいましたね。友人たちも巻き込んでいます。
この演習では、CardのコレクションはSet Cardで表します。というのも、存在するカードをすべて集めることが目標なら、重複したカードは重要ではないからです。
友人たちにもBlorkemon™️の熱狂に加わってほしいですよね。その一番の方法は、カードを1枚あげてコレクションのきっかけを作ることです。
newCollectionを実装しましょう。これはカードをコレクションに変換します。
newCollection "Newthree"
--> Set.fromList ["Newthree"]
コレクションができると、それは独りでに生き始め、育てていく必要があります。
addCardを実装しましょう。これはCardとコレクションを受け取り、2つの値を持つTupleを返します。1つはCardがすでにコレクションに入っていたかを示すBool、もう1つはカードを追加したコレクションです。
addCard "Scientuna" (Set.fromList ["Newthree"])
--> (False, Set.fromList ["Newthree", "Scientuna"])
友人たちがまたBlorkemon™️に夢中になったので、カードを交換して自分のコレクションを育てられます。
すべての交換が価値があるわけでも、そもそもできるわけでもありません。持っていないカードは交換に出せませんし、すでに持っているカードと交換するべきでもありません。
tradeCardを実装しましょう。これは交換する2枚のカード(自分のものと相手のもの)と、現在のコレクションを受け取ります。戻り値は2つの値を持つTupleです。1つはその交換が可能で価値があるかを示すBool、もう1つは交換した場合に最終的に手に入るコレクションです(実際には不可能であっても)。
tradeCard "Scientuna" "Newthree" (Set.fromList ["Scientuna"])
--> (True, Set.fromList ["Newthree"])
フリーマーケットで古いカードの隠し場所を見つけました。カードを並べ替えて重複を取り除き、そのリストと自分のコレクションを比べる必要があります。
removeDuplicatesを実装しましょう。これはカードのリストを並べ替え、並べ替え済みで重複のないカードのリストを返します。
removeDuplicates ["Newthree", "Newthree", "Newthree", "Scientuna"]
--> ["Newthree", "Scientuna"]
自分のコレクションを誇りに思う時です。
extraCardsを実装しましょう。これは自分のコレクションと他のコレクションを受け取り、他のコレクションが持っていないカードの数を返します。
extraCards (Set.fromList ["Scientuna"]) (Set.fromList ["Newthree", "Scientuna"])
--> 0
Blorkemon™️好きの友人たちと集まって、どのカードが一番よくあるのか気になりました。
boringCardsを実装しましょう。これはコレクションのリストを受け取り、すべてのコレクションが持っているカードを並べ替えたリストを返します。
boringCards [Set.fromList ["Scientuna"], Set.fromList ["Newthree", "Scientuna"]]
--> ["Scientuna"]
あなたと友人たちは、合わせてBlorkemon™️のカードを全部持っているでしょうか?
totalCardsを実装しましょう。これはコレクションのリストを受け取り、すべてのコレクションにある異なるカードの合計数を返します。
totalCards [Set.fromList ["Scientuna"], Set.fromList ["Newthree", "Scientuna"]]
--> 2
もうすぐ甥っ子が遊びに来ます。彼を驚かせたくなりました。子どもはキラキラしたものが好きですよね? Blorkemon™️のカードはキラキラにできるんです!
splitShinyCardsを実装しましょう。これはコレクションを受け取り、2つの並べ替え済みカードリストを持つTupleを返します。1つは"Shiny"で始まるすべてのカード、もう1つはそれ以外のカードです。
splitShinyCards (Set.fromList ["Newthree", "Scientuna", "Shiny Scientuna"])
--> (["Shiny Scientuna"], ["Newthree", "Scientuna"])