Сначала вам нужно сгенерировать все наборы. replicateM
из Control.Monad помогает с этим.
λ> replicateM 2 [1..4]
[[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[2,4],[3,1],[3,2],[3,3],[3,4],[4,1],[4,2],[4,3],[4,4]]
Затем вам нужно отфильтровать пары, где второй элемент больше первого
λ> filter (\[x,y] -> x < y) $ replicateM 2 [1 .. 4]
[[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
Наконец, вам нужно преобразовать каждый список в кортеж
λ> map (\[x,y] -> (x,y)) $ filter (\[x,y] -> x < y) $ replicateM 2 [1 .. 4]
[(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)]
Тогда мы можем сформулировать это в функцию pairs
:
import Data.Set
import Control.Monad
import Data.List
mySet = Data.Set.fromList [1,2,3,4]
--setOfPairs = Data.Set.fromList [(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)]
setOfPairs = Data.Set.fromList $ pairs mySet
pairs :: Ord a => Set a -> [(a,a)]
pairs x = Data.List.map (\[x,y] -> (x,y)) $ Data.List.filter (\[x,y] -> x < y) $ replicateM 2 $ toList x
Итак, если я правильно понял вопрос, вы можете использовать pairs mySet
, где пары генерируют список всех неупорядоченных пар mySet
.
Это то, что вы хотите?
UPD
Понимание списка может быть более понятной и быстрой техникой для создания таких подсписков, поэтому вот еще один пример pairs
:
pairs :: Ord a => Set a -> [(a,a)]
pairs set = [(x,y) | let list = toList set, x <- list, y <- list, x < y]