While trying to generate power set for a given list, I came across this function over the internet. There was no explanation, but testing suggests that it seems to work correctly. I am not able to understand how this function is working. I will be thankful for any such explanations.
generateSubset [] = [[]]
generateSubset (x:xs) = let p = generateSubset xs in p ++ map (x:) p
Here’s a property of powersets that’s easy to prove: P(A ∪ B) = {a ∪ b | a ∈ P(A), b ∈ P(B)}. In particular, if we decompose a particular set S into an element s and all the elements S’ that are not s, then
Now, P({s}) is small enough that we can compute it by hand: P({s}) = {{}, {s}}. Using this fact, we learn
That is, one way to compute the powerset of a non-empty set is to choose an element, compute the powerset for the remainder, then either add or don’t add the element to each of the subsets. The function you showed simply turns this into code, using lists as a representation of sets:
The only thing left is to give a base case for the recursion, and that just comes straight from the definition of a powerset: