次の (最適ではない) コードは、特定のサブセットに対してサイズ N のすべてのサブセットを生成します。
このコードは機能しますが、前述のとおり、非常に最適ではありません。中間リストを使用して Set.insert の O(log(n)) を回避することは、後でリストを Set に再変換するコストが大きいため、役に立たないようです。
コードを最適化する方法を提案できる人はいますか?
import qualified Data.Set as Set
subsetsOfSizeN :: Ord a => Int -> Set.Set a -> Set.Set (Set.Set a)
subsetsOfSizeN n s
| Set.size s < n || n < 0 = error "subsetOfSizeN: wrong parameters"
| otherwise = doSubsetsOfSizeN n s
where doSubsetsOfSizeN n s
| n == 0 = Set.singleton Set.empty
| Set.size s == n = Set.singleton s
| otherwise =
case Set.minView s of
Nothing -> Set.empty
Just (firstS, restS) ->
let partialN n = doSubsetsOfSizeN n restS in
Set.map (Set.insert firstS) (partialN (n-1)) `Set.union` partialN n