You've mentioned you've implemented toList
. You can use it to go the lists route here.
Just as in your previous question, this calls for implementing and using fromAscendingList
, to construct a tree from a list in a purely structural manner, without any comparisons, under the assumption that the list is already ordered in an increasing order.
This structural construction doesn't involve any knowledge of the elements; same should be true for the powerset function:
powerSet :: Set a -> Set (Set a)
powerSet = toList >>> powerList >>> map fromAscendingList
>>> fromAscendingList
-- (foo >>> bar >>> baz) x = baz (bar (foo x))
Of course we need to implement powerList
in an order-preserving fashion, for this to work properly:
powerList :: [a] -> [[a]]
powerList = concat . powers
where
powers :: [a] -> [ [[a]]]
powers [] = [ [[]] ]
powers (x:xs) = [ [[]] ] ++
[ map (x:) a ++ b
| (a:b:_) <- tails (powers xs ++ [[]]) ]
-- > powerList [1,2,3]
-- [[], [1],[2],[3], [1,2],[1,3],[2,3], [1,2,3]]
(a simpler alternative generates the sublists in a different order:
powerList' :: [a] -> [[a]]
powerList' (x:xs) = [ s | s <- powerList' xs, s <- [s, x:s]]
powerList' [] = [[]]
-- > powerList' [1,2,3]
-- [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
and if we'd followed the set-notation pseudocode in the other answer directly, the resulting code would produce the sublists even more out of order -- [3]
would come out before [2]
, and that before [1]
).
You still need to implement fromsAcendingList
. The simplest way is to just create the highly-unbalanced, list-like tree. You can start with that. Then perhaps devise a way to create the nearly-balanced tree, which is preferable.
As an alternative, treat all of the above as an executable specification and re-implement it to work directly on your Set
type values. mapTree
is trivial (and already covered in your previous question); simultaneously accessing a node and its successor in the fringe is also doable.
As a curiosity, I include also a version which generates the longest sublists first, for comparison:
-- shortest first:
powers :: [a] -> [ [[a]]]
powers [] = [ [[]] ]
powers (x:xs) = [ [[]] ] ++
[ map (x:) a ++ b | (a:b:_) <- tails (powers xs ++ [[]]) ]
-- longest first:
rpowers :: [a] -> [ [[a]]]
rpowers [] = [ [[]] ]
rpowers (x:xs) =
[ map (x:) b ++ a | (a:b:_) <- tails ([[]] ++ rpowers xs) ]
++ [ [[]] ]
> powers [1,2,3]
[[[]], [[1],[2],[3]], [[1,2],[1,3],[2,3]], [[1,2,3]]]
> rpowers [1,2,3]
[[[1,2,3]], [[1,2],[1,3],[2,3]], [[1],[2],[3]], [[]]]
toList
, how to find a power set of a list, and how to writefromList
, but not how to find a power set of aSet
? – SippetfromList
, notfromAscendingList
. so they needinsert
, which needsOrd
onSet
s. perhaps that's the problem they are having. they really should implementfromAscendingList
to use here (and in the previous question where I've left that function unimplemented and they haven't followed up on that). – Sievert