Понимание списка Haskell для переменного числа строк - PullRequest
6 голосов
/ 04 января 2012

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

 combineStrings firstStr sndStr = [ [a,b] | a <- firstStr, b <- sndStr]

Для трех строк я использую это

 combineStrings firstStr sndStr trdStr = [ [a,b,c] | a <- firstStr, b <- sndStr, c <- trdStr]

То, что я пытаюсь эточтобы получить тот же результат для переменного числа строк.Например, если у меня есть функция, которая принимает следующую форму:

 combineStrings :: [String] -> [String]

Я пытаюсь получить те же результаты, что и выше для 2, 3 ... n списков ... Я пробовал несколько способов,как этот

 combineStrings []      = []
 combineStrings (hd:tl) = [ a:b | a <- hd, b <- combineStrings tl]

, но это не удается из-за [] в первом предложении.Может кто-нибудь помочь мне написать это, пожалуйста?

Ответы [ 2 ]

15 голосов
/ 04 января 2012

Примечательно: Haskell уже имеет эту функцию, чуть более общую:

Prelude> :t sequence
sequence :: Monad m => [m a] -> m [a]
Prelude> sequence ["ab","cd","12"]
["ac1","ac2","ad1","ad2","bc1","bc2","bd1","bd2"]

[] является экземпляром Monad, поэтому в этом случае подпись становится sequence :: [[a]] -> [[a]], с1007 *, sequence :: [String] -> [String].

9 голосов
/ 04 января 2012

Попробуйте

combineStrings [] = [""]

или лучше (как указано sdcwc ):

combineStrings [] = [[]]

В противном случае часть b <- combineStrings tl понимания списка не даст никакого b, и вы всегда получите пустой массив.

Это также имеет смысл как крайний случай: единственный способ объединить символы из нулевых строк - это пустая строка (состоящая из нулевых символов).

...