Skip to content

Instantly share code, notes, and snippets.

@angerman
Last active May 3, 2018 20:39
Show Gist options
  • Save angerman/b70a53dac23d76602da6 to your computer and use it in GitHub Desktop.
Save angerman/b70a53dac23d76602da6 to your computer and use it in GitHub Desktop.
Powersets in Haskell
powerset :: [a] -> [[a]]
powerset [] = [[]]
powerset (x:xs) = map (x:) (powerset xs) ++ powerset xs
@chrisbloecker
Copy link

Powerset always twists my head... and I just came across your gist and this nice version, in case you haven't seen it:

powerset :: [a] -> [[a]]
powerset = filterM (const [True, False])

@Abhiroop
Copy link

Abhiroop commented Apr 5, 2018

@chrisbloecker Internally filterM is doing something very similar to what @angerman's version is doing. The True and False are the 2 cases. A list monad essentially represents non-determinism, and hence it takes all the cases. So here [True,False], filterM will happen for both True as well as False. When the predicate is True it takes the first branch (map (x:) (powerset xs) ) and when it is False it takes the second branch powerset xs.

It is quite simple to grok if you observe 2 things:

  1. The bind instance of List monad
  2. The definition of the filterM function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment