今、あなたが何をしようとしているのかを理解するのは少し難しいですが、あなたが抱えている問題は、フィルタリングとマッピングを何度も行うことだと思います.
必要なものを取得する簡単な方法は次のとおりだと思います。
module Combinations where
import Data.List (delete)
combs :: Eq a => Int -> [a] -> [[a]]
combs 0 _ = [[]]
combs i xs = [ y:ys | y <- xs, ys <- combs (i-1) (delete y xs) ]
から使用delete
するData.List
組み合わせをすばやく見つけるのに十分なほど怠惰なはずです-もちろん、すべてに時間がかかります;)
λ> take 5 $ combs 5 [1..52]
[[1,2,3,4,5],[1,2,3,4,6],[1,2,3,4,7],[1,2,3,4,8],[1,2,3,4,9]]
どのように機能しますか
y
これは、すべてのカードから最初のカードを選択することによって機能する再帰的組み合わせアルゴリズムの 1 つであり、リストモナド内でxs
再帰的に get s the rest of the hand
ys y:ys` をfrom the deck without the selected card
削除します (ここではリスト内包表記を使用しています)。and then putting it back together
ところで: そのようなデッキは 311,875,200 あります ;)
リスト内包表記なしのバージョン
システムに問題がある場合に備えて、理解のないバージョンを次に示します。
combs :: Eq a => Int -> [a] -> [[a]]
combs 0 _ = [[]]
combs i xs = do
y <- xs
ys <- combs (i-1) (delete y xs)
return $ y:ys
順列を削除するバージョン
これは、アイテムを昇順でソートOrd
するために使用し、その際に順列に関して重複を削除します-これが機能するためには、事前にソートされることが期待されます!xs
注意: chi のバージョンはより少ない制約で動作しており、より優れたパフォーマンスを発揮する可能性もありますが、これは素晴らしく読みやすく、以前のバージョンとうまくいくと思うので、興味があるかもしれません。
Haskell/FP では、最も一般的で抽象的なケースをめぐって争うことはよくあることではありませんが、私はほとんどの人が読みやすさと理解 (コンパイラーのためだけでなくプログラマーのためのコーディング) を目指して努力する環境を形成しています。 ;)
combs' :: Ord a => Int -> [a] -> [[a]]
combs' 0 _ = [[]]
combs' i xs = [ y:ys | y <- xs, ys <- combs' (i-1) (filter (> y) xs) ]