2017-02-23 55 views
0

我寫了下面的代碼,它應該取值列表並只打印values > average,將它們修改爲val - avg。 例如printModVal [9,0,6]應打印4 1,每行一個元素,使用System.IOprint函數。Haskell,用地圖打印修改後的列表值

import Data.List 
import System.IO 

printModVal :: [Float] -> IO() 
printModVal xs = ??? 
    where 
    average = (foldr (+) 0 xs)/genericLength xs 
    --use map here and print the values > average as value-average 


modVal :: Float -> Float -> Float 
modVal x y = x - y 


mapVal :: (a->b) -> [a] -> [b] 
mapVal f [] = [] 
mapVal f (x:xs) = f x : mapVal f xs 

我想知道如何,在這一點,我怎樣才能使用mapVal(與modVal作爲映射函數)的函數printModVal內,爲了打印值> 0(一旦被改性映射功能)。 謝謝。

+1

交換'modVal'的參數。然後它可以用作'(modVal average)'而不是'(\ x - > modVal x average)'。 –

回答

3

您必須應用過濾器。

要麼到結果列表

printModVal xs = mapM_ print $ filter (> 0) (mapVal (\x -> modVal x average) xs) 
    where 
    average = (foldr (+) 0 xs)/genericLength xs 

,或者進入的列表

printModVal xs = mapM_ print $ mapVal (\x -> modVal x average) (filter (> average) xs) 
    where 
    average = (foldr (+) 0 xs)/genericLength xs 

map並不會改變它的進程列表的長度。 簽名爲(a->b)->[a]->[b]的任何函數由於參數的原因在其功能上非常有限。

+1

這看起來是正確的,但顯然'printModVal'需要在屏幕上打印列表,而不是返回它,因爲它的返回類型是'IO()'。 – chi

+0

你說得對。我只是不習慣於同時做很多事情的功能。 –

+0

事實上,在IO中Haskell將計算與IO分離非常習慣。 – chi