问题
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:
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.
回答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 String
s 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
回答3:
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
回答4:
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
来源:https://stackoverflow.com/questions/7862221/how-do-i-do-string-replace-in-haskell