在haskell中将字符替换为数字

时间:2014-03-30 16:52:56

标签: haskell

我有函数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" 

我该怎么做?

2 个答案:

答案 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[Char]是等价的),它不符合类型签名。

所以解决方案是将我们不关心的其他字符包装到列表中,之后,我们可以执行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]