2014-03-30 17 views
1

我有功能change,它將某些字符替換爲數字。那就是:將字符替換爲haskell中的數字

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" 

我怎樣才能做到這一點?

+1

您否則子句失去X的簡寫。我對Haskell不是很熟悉,但是你可能想'否則= x:改變cs' –

回答

1

除了@kostya的答案,你不需要寫遞歸部分youself,嘗試了這一點:

​​

,或者更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(在Haskell中的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] 
7

試試這個:

change [] = [] 
change (x:xs) | x == 'A' = '9':'9':change xs 
       | x == 'B' = '9':'8':change xs 
       | otherwise = x:change xs 

唯一的變化是在其他。