0

I am having trouble with a couple list problems. The first is supposed to insert a string between strings, as long as the strings are the same length, ie inserts "da" [("so","ed"),("c",""),("",""),("mo","le")] would return ["sodaed" "da" "modale"]

so far I have

inserts :: String -> [(String, String)] -> [String]
inserts str pairs = [[x,str,z] | (x,z) <- pairs, length (x) == length (z)]

inserts' :: String -> [(String, String)] -> [String]
inserts' [] [] = []
inserts' str [(x:xs),(y:ys)] 
    | (length y) == (length x) = (x, str, y) : inserts' str [xs,ys]
    | otherwise = inserts' str [x,ys]

I am getting a type error though matching [char] to string

1
  • Can you post the actual error message you're getting? Commented Feb 27, 2014 at 21:03

2 Answers 2

2

You're really close! I'm pretty sure the error message you're getting is something different than not being able to match [Char] and String though, because these are the same!

Let's see what happens when we remove the type signature on inserts (I'm doing this in ghci, but you can of course try it via a file as well):

Prelude> let inserts str pairs = [[x,str,z] | (x,z) <- pairs, length x == length z]
Prelude> :t inserts
inserts :: [a] -> [([a], [a])] -> [[[a]]]

OK, that's a pretty general type. As you might know, String is the same as [Char]. So if we substitute Char for a in the type of inserts, and replace [Char] by String, we can see that the inserts can specialize to String -> [(String,String)] -> [[String]].

So the arguments match, but the result has one level of lists too many. That's pretty logical, since x,str and z are strings, so [x,str,z] is a list of strings. All that's needed is to concatenate these three strings into one.

Either you can append the lists 'by hand', using x ++ str ++ z as the expression on the left side of the list comprehension, or you could use concat [x,str,z] to do it; concat flattens a list of lists (of Characters in this case) into a list.


For your second try, you can use something similar instead of the three-tuple of strings (x, str, y), do you see what you need to do?

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

Comments

0

For the type to be correct, I think for the first function should be:

inserts :: String -> [(String, String)] -> [String]
inserts str pairs = [x ++ str ++z | (x,z) <- pairs, length (x) == length (z)]

or

inserts :: String -> [(String, String)] -> [[String]]
inserts str pairs = [[x,str,z] | (x,z) <- pairs, length (x) == length (z)]

, depending on your needs.

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.