2012-03-11 40 views
12

我有三個詞在列表[「a」,「b」,「c」]。我想找到所有可能的組合設置5,6等哈斯克爾組合和排列

例如用於一套5我將不得不上述

**[ [aaaaa],[aaaab],[aaaac], [aaabc] , ..... ]** etc 3^5 = 243 combinations 

AAAAAA將基本上是「一」,「一」,「一」 「一」,「一」 ....

+0

我從昨天開始工作。沒有更進一步。如果我能得到一些想法,那麼我可能會做到這一點。 – Waqas 2012-03-11 20:17:20

+2

@ user1115751:要開始搜索「[haskell cartesian product](http://stackoverflow.com/search?q=haskell+cartesian+product&submit=search)」。 – kennytm 2012-03-11 20:19:10

回答

20

replicateM你想要做什麼:

> import Control.Monad 
> replicateM 5 ["a", "b", "c"] 
[["a","a","a","a","a"],["a","a","a","a","b"],["a","a","a","a","c"],["a","a","a","b","a"],["a","a","a","b","b"],["a","a","a","b","c"],["a","a","a","c","a"],["a","a","a","c","b"],["a","a","a","c","c"],["a","a","b","a","a"],["a","a","b","a","b"],["a","a","b","a","c"],["a","a","b","b","a"],["a","a","b","b","b"],["a","a","b","b","c"]...] 
20

當然,nanothief的回答給出了最短的解決方案,但它可能是有益和好玩自己做。

有很多方法可以爲笛卡爾積寫一個函數。例如。您可以使用列表理解:

prod :: [[a]] -> [[a]] -> [[a]] 
prod as bs = [a ++ b | a <- as, b <- bs] 

(++) :: [a] -> [a] -> [a] - 見Data.List。另一種可能是使用列表的Applicative實例:

import Control.Applicative 

prod as bs = (++) <$> as <*> bs 

現在,你需要反覆應用此操作。的摺疊可以做到這一點,例如:

rep :: Int -> [[a]] -> [[a]] 
rep n as = foldr1 prod $ replicate n as 

rep 3 ['a','b','c'] 
--["aaa","aab","aac","aba","abb","abc","aca","acb","acc","baa","bab", 
--"bac","bba","bbb","bbc","bca","bcb","bcc","caa","cab","cac","cba", 
--"cbb","cbc","cca","ccb","ccc"] 

瞭解這個解決方案可能比服用replicateM快捷更有價值。也就是說,你可以使用Hoogle輕鬆找到後者。

-

更多關於函子和應用型見定義fmap<$>)和ap<*>)。 Functors, Applicatives, And Monads In Pictures也可以是一個很好的資源。

+0

這不會編譯。對於傳遞給'++'的操作數必須有一個類型約束。 – dopatraman 2016-06-11 23:20:13

+0

我在GHCi中試過這個,它在沒有限制的情況下工作。 – Landei 2016-06-12 19:20:17

+0

例如,你會如何修改數字?還是其他類型? – dopatraman 2016-06-12 20:48:58