2017-02-05 11 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'の行に沿って' avg'を何かと定義する 'where'または' let'バインディングを付けることを可能にします。 – 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

あなたはそれを釘付け、どのように私はそれを考えることができなかったか分からない、ありがとう! –