Reputation: 1
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
Upvotes: 0
Views: 979
Reputation: 6610
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 Char
acters 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?
Upvotes: 2
Reputation: 22460
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.
Upvotes: 0