Reputation: 43
I have been trying to learn Haskell and currently trying to make a recursive "dictionary" or "translator" function. Basically it should receive an array of stings like and an array of tuples or sting, and return an array of strings that has elements replaced by tuple's 2nd part if it matched 1st one. So basically from
["a", "b", "zz"] [("a", "11"),("b","c")]
to
["11","c","zz"]
Having trouble making it... this is what I have so far:
aa (x:xs) (y:ys) = do
-- iterate through y
if ys == [] then return(x:xs) else aa (x:xs)(ys)
-- iterate through x
if xs == [] then return(x:xs) else aa (xs)(y:ys);
if x == fst(y)
then do
putStrLn("Yes");
return (snd(y):xs);
else return (x:xs);
which worked for 1st element of the array. I can't seem to figure out how do I make it go through. Also removing putStrLn causes error "mismatched" brackets, why?
While trying to figure it out also tried storing the result, and it didn't work out:
aa (x:xs) (y:ys) = do
if x == fst(y)
then result <- snd(y):xs
else result <- x:xs
return result;
resulted in an error "parse error on input '<-' Perhaps this should be in a 'do' block?"
Upvotes: 1
Views: 528
Reputation: 1359
This is not too tricky a problem to solve if we break it down. Firstly we want a function which takes a list of tuples, and a key, and returns the value of that key if it exists in the list.
Fortunately this is already defined for us, with lookup
It returns a Maybe value. If we don't find it, then we don't need to replace it, so we can simply return the original value. fromMaybe does this for us, it takes a default value and a maybe value, and if the maybe value is a Just, it returns the value in the just.
Now we just need to map over the list, and for each item, replace it with the item in the association list if it exists, or if not, replace it with itself.
And here's the code:
import Data.Maybe (fromMaybe)
translator xs ys = map replace xs
where replace x = fromMaybe x (lookup x ys)
Your code has a few issues in that you appear to be trying to use do notation when it's not really needed. When you're a beginner, generally you should just be using do notation in functions where you use IO. If you want to define something to prevent everything being one long statement, you can use where or let.
λ> translator ["a", "b", "zz"] [("a", "11"),("b","c")]
["11","c","zz"]
λ>
Upvotes: 4