2016-01-26 3 views
0

Я пытаюсь получить перестановки переменного количества строк в списке. Я уверен, что это возможно в Haskell, мне просто трудно найти ссылку для этого ,Динамическое число элементов для определения списка

Я ищу, чтобы быть в состоянии сделать это [ [n1] ++ [n2] ++ etc | n1 <- {first string}, n2 <- {second string}, etc ]

Где мой список может быть ["hey", "now"]

и мой результат будет выглядеть следующим образом:

["hn","ho","hw","en","eo","ew","yn","yo","yw"]

Как бы я мог сделать что-то подобное?

+0

Вы хотите грубую силу или элегантность? – BalinKingOfMoria

+0

@BalinKingOfMoria оба? :) – bruchowski

ответ

11
> sequence ["hey", "now"] 
["hn","ho","hw","en","eo","ew","yn","yo","yw"] 

sequence является очень общим, но в списках вы можете думать о нем, как если бы она была определена следующим образом:

sequence :: [[a]] -> [[a]] 
sequence [] = [[]] 
sequence (x:xs) = [ y:ys | y <- x, ys <- sequence xs ] 

Результат выше иногда называют «декартово произведение» списка списков, так как оно аналогично операции на множествах.

+0

Ох. Это намного приятнее. – BalinKingOfMoria

+0

делает много смысла, спасибо большое – bruchowski

+1

Тип и определение тела 'sequence' здесь не совсем верно. Первое обязательство в понимании ошибочно. –

1

EDIT: Это работает только для строк длиной 2, но показывает desugaring из списка понимания (с return является concat и fmap является map, если я помню).

Вот это грубая сила для этого (если вы хотите знать возможный подход). Если вам нужна чистая версия, см. chi's answer.

concat $ map (\char1 -> map (\char2 -> char1:[char2]) string2) string1 должен это сделать. Возможно, лучший способ с учетом списка, но это тоже делает работу.

Объяснение:

concat $ -- Flatten lists 
    map (\char1 -> -- Iterate over each character of string1 
    map (\char2 -> -- Iterate over each character of string2 
     char1 : [char2] -- Add char1 to char2 
    ) string2 
) string1 
+0

Это работает только для ровно двух строк, а не списка любого размера, о чем спрашивает вопрос. Оригинальный фрагмент OP работает отлично для двух строк. (также, 'x: [y]' - просто странный способ записи '[x, y]'). – amalloy

+0

@amalloy О да. Дело 'x: [y]' в том, что я относительно новый (и ржавый), но вы совершенно правы (думаю, я интерпретировал этот вопрос как строку с переменной длиной). Вы порекомендовали бы я удалить этот ответ или предоставить ему образовательное значение (я не хочу, чтобы его забросили в забвение ...)? – BalinKingOfMoria

+0

Не так много в [haskell] получает downvoted до забвения, поэтому я бы не стал беспокоиться об этом. Если вы считаете, что ваш ответ по-прежнему поучителен, вы можете оставить его, возможно, с помощью редактирования, чтобы выяснить, какую проблему он решает; или вы можете удалить его. Я проигнорировал, потому что я думаю, что это не полезно, но два человека поддержаны, возможно, потому, что это хорошее обескураживание понимания списка. Это полностью зависит от вас. – amalloy

Смежные вопросы