Подтвердить что ты не робот

Комбинации и перестановка Haskell

У меня есть три слова в списке [ "a" , "b", "c" ]. я хочу найти все возможные комбинации в наборе 5,6 и т.д.

например, для набора из 5 я было бы

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

aaaaaa выше будет в основном "a" , "a" , "a" , "a" , "a" ....

4b9b3361

Ответ 1

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"]...]

Ответ 2

Конечно, ответ на 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 (<*>). Функторы, Применения и Monads In Pictures также могут быть хорошим ресурсом.