答案 0 :(得分:3)
我不确定上面示例中replace
的来源。但是......假设它存在,并按照您的期望行事,您应该能够从(:)
函数中删除缺点strRep
,而是将替换结果传递给下一次strRep运行,像这样:
strRep :: (Show a) => M -> String -> String
strRep [] s = s
strRep (m:ms) s = strRep ms (replace (fst m) (snd m) s)
现在,不是返回一个字符串列表,而是每个版本都替换了一个东西。您正在迭代地替换每个字符串,传递新字符串以进行下一次替换。
答案 1 :(得分:2)
使用折叠几乎总能实现在haskell中的循环 因此,在您的示例中,您需要通过连续替换从映射中获取的字符串来构建结果。
让我们使用严格的折叠:
import Data.List(foldl')
然后你的strRep
会是这样的:
strRep :: M -> String -> String
strRep m input = foldl' replace input m
或者更短一些:
strRep = flip $ foldl' replace
处理String
的表现相当糟糕。更好的选择是从Text
处理Data.Text
然后replace
非常直接:
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
答案 2 :(得分: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
答案 3 :(得分:0)
解决问题的另一种不同方法
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