2017-02-05 71 views
1

假設我有以下功能保存變量,並用它在遞歸

printVariance :: [Float] -> IO() 
printVariance [] = return() 
printVariance (x:xs) 
    | x >= avg (x:xs) = print (x - avg (x:xs)) >> printVariance xs 
    | otherwise  = printVariance xs 

它得到一個列表,檢查哪些元素是比一般的大,並打印自己的value - avg

我的問題是avg值每一步都會改變。我怎樣才能定義它一次並使用它的遞歸值呢?

+2

您可能需要使用摺疊和貼圖來重寫,而不是直接遞歸。這將允許你在'(foldr(+)0 xs)/ length xs'的行上附加一個'where'或'let'綁定,你將'avg'定義爲某些東西。 – Michail

回答

6

將遞歸移動到輔助函數中。該函數可以將平均值作爲參數,也可以在本地定義爲printVariance並定義另一個保持平均值的局部變量,然後該函數可以訪問該平均值。

在代碼:

printVariance :: [Float] -> IO() 
printVariance xs = loop xs 
    where 
    average = avg xs 
    loop [] = return() 
    loop (x:xs) 
     | x >= average = print (x - average) >> loop xs 
     | otherwise = loop xs 

PS:這將是良好的設計到IO從程序邏輯分離。所以我建議你讓你的函數只是產生一個你想要的值列表,而不是打印它們並把IO移動到一個單獨的函數中(或者只是main)。

PPS:你沒有真正計算方差,所以我建議將函數命名爲別的。

+1

啊,我們寫了同樣的程序。爲了簡潔起見,我會刪除我的答案:) – AJFarmar

+0

你釘了它,我不知道我怎麼也想不到,謝謝! –