2017-02-05 72 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

你钉了它,我不知道我怎么也想不到,谢谢! –