6

If I have two strings I use a list comprehension to obtain the desired result:

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

For three strings, I use this

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

What I'm trying is to obtain the same result for a variable number of strings. For example if I have a function which takes the following form:

 combineStrings :: [String] -> [String]

I'm trying to obtain the same results as above for 2, 3 ... n lists... I tried multiple ways, like this one

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

but this fails because of [] on the first clause. Can someone help me to write this, please?

1
  • 3
    As a general rule, you can try to make types as general as possible. Here your code is not specific to strings, and can be used for all lists, so you can write combineStrings :: [[a]] -> [[a]]. Then, the first line from undur_gongor's answer can be written combineStrings [] = [[]]. You can also try to write combineStrings using foldr, as it fits the fold pattern. Commented Jan 4, 2012 at 14:33

2 Answers 2

15

Noteworthy: Haskell already has that function, just a bit more general:

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

[] is an instance of Monad, so in this case the signature becomes sequence :: [[a]] -> [[a]], with a = Char, sequence :: [String] -> [String].

Sign up to request clarification or add additional context in comments.

4 Comments

I wonder how many functions like this are re-written by newcomers like me.. But it's a learning experience :) Thank you
Many. And it's a good thing, as long as they're told soon enough that there's a (more general, usually) function in the standard libraries already, because, as you said, it's a very good learning experience. Just, once you've figured out how it works by writing your own version, use the library function other Haskellers already know.
Hoogle and HLint are there to help you.
@Adi @DanielFischer And actually, at this point, a good exercise would be to write one's own implementation of sequence. These simple-but-very-general functions always make good learning exercises.
9

Try

combineStrings [] = [""]

or better (as pointed out by sdcwc):

combineStrings [] = [[]]

Otherwise the part b <- combineStrings tl of the list comprehension will not yield any b and you will always end up with an empty array.

It also makes sense as an edge case: The only way to combine characters from zero strings is an empty string (consisting of zero characters).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.