2015-11-12 31 views
0

我想將列表的每個第二個元素加倍。以下是代碼 -減少Haskell函數

doubleSec n [] = [] 
doubleSec n (x:xs) 
    | n==1 = x*2 : doubleSec 0 xs 
    | otherwise = x : doubleSec 1 xs 

doubleSecond xs = 
    doubleSec 0 xs 

如何在單個函數中壓縮此邏輯?

回答

3

這個怎麼樣

doubleSecond xs = map (\(x,i) -> if odd i then x*2 else x) (zip xs [0..]) 
8

可以匹配這樣

doubleSec :: [Int] -> [Int] 
doubleSec [] = [] 
doubleSec [x] = [x] 
doubleSec (x : y : xs) = x : 2* y : doubleSec xs 

名單上的圖案讓你做具體的事情,第二個元素

2

這種方法將保留O(n)的運行時間:

doubleSecond xs = 
    [ if isOddStep then 2 * x else x | 
    (isOddStep, x) <- zip (cycle [False, True]) xs ] 

@DavidFletcher的更簡潔的版本:

doubleSecond = zipWith ($) (cycle [id, (2*)]) 

或:

doubleSecond = zipWith id (cycle [id, (2*)]) 

如通過@Carl建議。

+6

如果你打算使用週期,那麼'zipWith($)(循環[ID,(2 *)])' –

+0

@DavidFletcher如果你打算高爾夫那'zipWith id'比'zipWith($)'略短(並且更容易輸入) – Carl