我有函数change
,它将某些字符替换为数字。这是:
change [] = []
change (x:xs) | x == 'A' = '9':'9':change xs
| x == 'B' = '9':'8':change xs
| otherwise = change xs
,输出为:
Main> change "aAB11s"
"9998"
但我需要这个:
Main> change "aAB11s"
"a999811s"
我该怎么做?
答案 0 :(得分:7)
试试这个:
change [] = []
change (x:xs) | x == 'A' = '9':'9':change xs
| x == 'B' = '9':'8':change xs
| otherwise = x:change xs
唯一的变化就在其他方面。
答案 1 :(得分:1)
除了@kostya的答案之外,你不需要自己编写递归部分,试试这个:
change :: String -> String
change xs = concatMap chToStr xs
where chToStr 'A' = "99"
chToStr 'B' = "98"
chToStr x = [x]
或更多point-freely(如果无点重构不会影响可读性,实际上这是首选的):
change :: String -> String
change = concatMap chToStr
where chToStr 'A' = "99"
chToStr 'B' = "98"
chToStr x = [x]
你可以测试结果:
λ> change "aAB11s"
"a999811s"
一些解释:
通过传递map
函数来进行元素替换是很诱人的
f :: Char -> Char
。但是在这里你不能这样做,因为对于A
,你需要两个字符,即99
,所以你想要的函数是Char -> String
类型String
和
所以解决方案是将我们不关心的其他字符包装到列表中,之后,我们可以执行string concatenation(Haskell中的这个函数称为concat)来获取回来了。
此外,concatMap f xs
只是concat (map f xs)
λ> map (\x -> [x,x]) [1..10]
[[1,1],[2,2],[3,3],[4,4],[5,5],[6,6],[7,7],[8,8],[9,9],[10,10]]
λ> concat (map (\x -> [x,x]) [1..10])
[1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10]
λ> concatMap (\x -> [x,x]) [1..10]
[1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10]