我想写一个带有字符串的Haskell函数,并用特殊代码%20替换任何空格字符。例如:
sanitize "http://cs.edu/my homepage/I love spaces.html"
-- "http://cs.edu/my%20homepage/I%20love%20spaces.html"
我正在考虑使用concat函数,因此我可以将列表列表连接到一个普通列表中。
答案 0 :(得分:3)
您正在寻找的高阶函数是
concatMap :: (a -> [b]) -> [a] -> [b]
在您的情况下,选择a ~ Char, b ~ Char
(并观察String
只是[Char]
的类型同义词),我们得到
concatMap :: (Char -> String) -> String -> String
所以一旦你写了一个函数
escape :: Char -> String
escape ' ' = "%20"
escape c = [c]
只需编写
即可解除对字符串的影响sanitize :: String -> String
sanitize = concatMap escape
答案 1 :(得分:2)
使用理解也可以,如下,
changer :: [Char] -> [Char]
changer xs = [ c | v <- xs , c <- if (v == ' ') then "%20" else [v] ]
答案 2 :(得分:1)
changer :: [Char] -> [Char] -> [Char]
changer [] res = res
changer (x:xs) res = changer xs (res ++ (if x == ' ' then "%20" else [x]))
sanitize :: [Char] -> [Char]
sanitize xs = changer xs ""
main = print $ sanitize "http://cs.edu/my homepage/I love spaces.html"
-- "http://cs.edu/my%20homepage/I%20love%20spaces.html"
sanitize
函数的目的是调用changer
来完成实际的工作。现在,changer
以递归方式调用自身,直到当前字符串耗尽。
changer xs (res ++ (if x == ' ' then "%20" else [x]))
它接受第一个字符x
并检查它是否等于" "
,如果是,则给出%20
,否则将实际字符本身作为字符串,然后我们将其连接到累积的字符串。
注意:这可能不是最佳解决方案。
答案 3 :(得分:0)
您可以使用intercalate
模块中的Data.List
功能。它使用给定的分隔符和列表执行intersperse
,然后对结果进行连接。
sanitize = intercalate "%20" . words
或使用模式匹配:
sanitize [] = []
sanitize (x:xs) = go x xs
where go ' ' [] = "%20"
go y [] = [y]
go ' ' (x:xs) = '%':'2':'0': go x xs
go y (x:xs) = y: go x xs
答案 4 :(得分:0)
Shanth的模式匹配方法的另一种表达方式:
sanitize = foldr go []
where
go ' ' r = '%':'2':'0':r
go c r = c:r