Reputation: 337
I need to create a Haskell "data Set"
data Set a = Set [a]
Exercise let's implement a simple Set datatype. A Set is a list of unique elements. The set is always kept ordered.
Implement the functions below. You might need to add class
constraints to the functions' types.
Examples:
member 'a' (Set ['a','b','c']) ==> True
add 2 (add 3 (add 1 emptySet)) ==> Set [1,2,3]
add 1 (add 1 emptySet) ==> Set [1]
data Set a = Set [a]
deriving (Show,Eq)
so far I defined :
-- emptySet is a set with no elements
emptySet :: Set a
emptySet = Set []
-- member tests if an element is in a set
member :: Eq a => a -> Set a -> Bool
member _ (Set[]) = False
member a (Set (x:xs))
| (a == x) = True
| otherwise = member a (Set xs)
but i'm struggling how to define the "add" method, it´s fail in the order test
-- add a member to a set
add :: Ord a => a -> Set a -> Set a
add a (Set[]) = Set[a]
add a (Set (x:xs))
| (a > x) && (not ( member a (Set (x:xs)) )) = add a (Set xs)
| (a <= x) && (not ( member a (Set (x:xs)) )) = Set ( a :(x:xs) )
| (not ( member a (Set (x:xs)) )) = Set ((x:xs) ++ [a])
| otherwise = Set (x:xs)
Tests failed:
*** Failed! Falsified (after 6 tests):
add (Just 0) (Set [Nothing,Just (-5),Just 1,Just 3])
Expected: Set [Nothing,Just (-5),Just 0,Just 1,Just 3]
Was: Set [Just 0,Just 1,Just 3]
so my question is , how to implement the Add method but keep the order correct. or it's easier to using a helper function to order the elements after insert.
Upvotes: 1
Views: 1099
Reputation: 337
the solution that i'm able to found , based on the @amalloy & @chi tips , was
toLista :: Set a -> [a]
-- toLista (Set[]) = []
-- toLista (Set (x:xs)) = [x] ++ toLista ( Set (xs))
toLista (Set lista) = lista
add :: Ord a => a -> Set a -> Set a
add a (Set[]) = Set[a]
add a (Set (x:xs))
| (a == x) = Set (x:xs)
| (a < x) = Set ( a :(x:xs) )
| otherwise = Set ( x : toLista ( add a (Set xs) ))
Upvotes: 1
Reputation: 71109
You write
add a (Set (x:xs))
| (a > x) && (not ( member a (Set (x:xs)) )) = add a (Set xs)
-- ^^^^^^^^^^^^^^
....
add a (Set xs)
is the result.
Where's x
? Shouldn't it be present in the result as well?
Upvotes: 1
Reputation: 92077
You shouldn't need a member
test in each iteration of your add
function, because you know the Set is sorted. Simply walk down the list, at each step comparing the element to be added with the front of the set. If the element to be added is equal to the smallest item, then you can stop: the element is already present. If it's less than the smallest item, then you've found its insertion point: if it's smaller than the smallest item, it must be smaller than all items, and thus should be added. Finally if the element to be added is larger than the smallest item, then just keep going until you find its insertion point.
Upvotes: 3