1

I've just started to learn Haskell and had difficult times of solving this problem: powerSet :: Set a -> Set (Set a)

Here's my attempt:

powerSet :: Tree a -> Tree (Tree a)
powerSet Empty = Empty
powerSet tree = fromList' [fromList' p | p <- powerSet' (toList tree)]

powerSet' :: [a] -> [[a]]
powerSet' [] = [[]]
powerSet' (x:xs) = [x:ps | ps <- powerSet' xs] ++ powerSet' xs

I should expect the output in such order: powerset {1,2,3} => { {}, {1}, {2}, {1,2,3}, {1,3}, {2}, {2,3}, {3} }

But instead I got this: powerset {1,2,3} => { {1,2,3}, {1,2}, {1,3}, {1}, {2,3}, {2}, {3}, {} }

Is there any way I can change it?

5
  • 1
    Why do you expect the order to be { {}, {1}, ... }? Commented Jan 14, 2020 at 22:31
  • 4
    A set is an unordered collection. Likely, you should disregard the order of the elements as they are printed. Commented Jan 14, 2020 at 22:41
  • 1
    Your implementation furthermore deals with a Tree, instead of a Set. Commented Jan 14, 2020 at 22:44
  • @WillemVanOnsem For what it's worth, if you change the first {2} to {1,2} in the expected output, then the subsets appear in lexicographical order; so perhaps the exercise is intended to encourage a search tree implementation. Commented Jan 14, 2020 at 23:05
  • 1
    @DanielWagner: ah yes. But then the fromList should thus insert the items in a ordered way. Then the "responsibility" is more for the tree generation part than for the powerSet' function. Commented Jan 15, 2020 at 8:45

1 Answer 1

0

Wondering if there's any way I can change it?

Well the order is { {1,2,3}, {1,2}, {1,3}, {1}, {1,3}, {2,3}, {2}, {3}, {} } because that is how you implemented this. Indeed for an empty list, you return as powerSet' [], a singleton list with an empty list. For a non-empty list, you recurse on the tail of the list, and first you yield that list where you each time prepend x to that list, and then you yield the result of the recursive call without prepending.

Hence for a list [2], the recursive case is [[]], so we first prepend it with 2 yielding [2], and then we do not prepend this, yielding [].

If we thus calculate the powerset of [1,2], the recursive call will result in [[2], []]. We first emit the list where we each time prepend 1, so [1,2] and [1], and then we emit the list without prepending, making it [2] and []. Or putting this together [[1,2], [1], [2], []].

You can yield the results in a different order, for example with:

powerSet' :: [a] -> [[a]]
powerSet' l = [] : go l
    where go [] = []
          go (x:xs) = [x] : map (x:) (go xs) ++ go xs

But as @DanielWagner says in his comment:

so perhaps the exercise is intended to encourage a search tree implementation.

You likely should not alter the order of the items that are yielded by the powerSet', but make sure your Tree is a (binary) search tree, and thus implement the fromList function in such way that it insert the items in an ordered manner in your Tree.

Sign up to request clarification or add additional context in comments.

1 Comment

yes I did use a BST and this explained my question very clearly. Many thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.