1

So I have the following list of tuples and a string


type M a = [(String, String)]
m = [
    ("x", "a car"),
    ("y", "a animal")
]
s = "this is x and y"

I am trying to

strRep m s => "this is a car and a animal"

So this is my attempt so far


import Data.List.Utils

strRep :: (Show a) => M -> String -> String
strRep [] s = s
strRep (m:ms) s = replace (fst m) (snd m) s : strRep ms s

The above code returns a list of string. I cant quite figure out the proper way to do loop here.

1
  • 1
    Can ou show your imports? Where are you getting replace from? Commented Oct 22, 2011 at 20:03

4 Answers 4

3

I'm not sure where replace is coming from in your example above. But... assuming it exists, and does what you expect, you should be able to remove the cons (:) from your strRep function, and instead pass the result of replace into the next run of strRep, like so:

strRep :: (Show a) => M -> String -> String
strRep [] s = s
strRep (m:ms) s = strRep ms (replace (fst m) (snd m) s)

Now, instead of returning a list of strings, each a version with one thing replaced. You are iteratively replacing each string, passing the new strings on for the next replacement.

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

1 Comment

Oops, replace is from Data.List.Utils
2

Looping in haskell can almost always be realized using a fold.
So in your example you need to build your result by consecutively replacing strings taken from your mapping.

Let's use a strict fold:

import Data.List(foldl')

Then your strRep would look like:

strRep :: M -> String -> String
strRep m input = foldl' replace input m

Or a little shorter:

strRep = flip $ foldl' replace

Dealing with Strings is performing rather poorly. A better alternative is to deal with Text from Data.Text.
Then replace is rather straight forward:

import qualified Data.Text as T

replace :: String -> (String,String) -> String
replace s (a,b) = let [ss,aa,bb] = [T.pack x | x <- [s,a,b]] in
  T.unpack $ T.replace aa bb ss

Comments

0
replace m w = case (lookup w m) of
                          Just w' -> w'
                          otherwise -> w

strRep :: [(String, String)] -> String -> String
strRep m s = unwords $ map (replace m) $ words s

Comments

0

Another different way to solve your problem

type M = [(String , String)]

m = [("x", "a car"),
     ("y", "a animal")]

lookUp :: String->M ->String
lookUp a lst =  head ( [ value| (key ,value ) <- lst , key == a])


strRep :: String ->M->String
strRep input replacements = unwords ( map repAux ( words input))
   where
     poss = map fst replacements
     repAux :: String -> String
     repAux x
       | elem x poss = lookUp x replacements
       | otherwise = x

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.