Search code examples
f#lazy-evaluationpowerset

Generate powerset lazily


I want to calculate powerset of a set. Because I don't need the whole powerset at a time, it's better to generate it lazily.

For example:

powerset (set ["a"; "b"; "c"]) =
seq {
  set [];
  set ["a"];
  set ["b"];
  set ["c"];
  set ["a"; "b"];
  set ["a"; "c"];
  set ["b"; "c"];
  set ["a";"b"; "c"];
}

Since the result is a sequence, I prefer it in the above order. How can I do it in an idomatic way in F#?

EDIT:

This is what I'm going to use (based on BLUEPIXY's answer):

let powerset s =
    let rec loop n l =
        seq {
              match n, l with
              | 0, _  -> yield []
              | _, [] -> ()
              | n, x::xs -> yield! Seq.map (fun l -> x::l) (loop (n-1) xs)
                            yield! loop n xs
        }   
    let xs = s |> Set.toList     
    seq {
        for i = 0 to List.length xs do
            for x in loop i xs -> set x
    }

Thanks everyone for excellent input.


Solution

  • let rec comb n l =
      match n, l with
      | 0, _  -> [[]]
      | _, [] -> []
      | n, x::xs -> List.map (fun l -> x ::l) (comb (n - 1) xs) @ (comb n xs)
    
    let powerset xs = seq {
        for i = 0 to List.length xs do
          for x in comb i xs -> set x
      }
    

    DEMO

    > powerset ["a";"b";"c"] |> Seq.iter (printfn "%A");;
    set []
    set ["a"]
    set ["b"]
    set ["c"]
    set ["a"; "b"]
    set ["a"; "c"]
    set ["b"; "c"]
    set ["a"; "b"; "c"]
    val it : unit = ()