答复: [Haskell-cafe] How to do this in FP way?

David Roundy droundy at darcs.net
Tue Jun 17 14:39:11 EDT 2008


On Tue, Jun 17, 2008 at 08:56:31AM -0700, Don Stewart wrote:
> dons:
> > magicloud.magiclouds:
> > > OK. Here it is.
> > > I want to make a monitor tool for linux. It runs for a long time, and give
> > > out a certain process's io stat per second. The way I get io stat is to read
> > > from /proc/pid/io. But the data in this file is a total, I need to read it
> > > first, then next second, read it again, and shows the difference, and go on.
> > > So, what is your idea?
> > 
> > Easy,
> > 
> >     import Control.Concurrent
> >     import Control.Monad
> > 
> >     main = go 0
> >         where
> >             go st = forever $ do
> >                        n <- read `fmap` readFile "/proc/pid/io"
> >                        print (n - st) -- display difference
> >                        threadDelay (10^6)
> 
> Oops, not 'forever' :)
> 
>               go st = do
>                     ...
>                     go n


or

doEverySecond :: (a -> IO a) -> a -> IO ()
doEverySecond job n = do n' <- job n
                         threadDelay (10^6)
                         doEverySecond job n'

showChange :: Int -> IO Int
showChange n = do n' <- read `fmap` readFile "/proc/pid/io"
                  print (n' - n) -- display difference
                  return n'

main = doEverySecond showChange 0 -- note: prints bogus value first time

This demonstrates how you can abstract the ideas in Don's solution
just a bit, so that you could reuse these functions for somewhat
different purposes.  For such a simple function you'd probably be
better with Don's solution, but if your monitor tool is starting to
look more complicated than this, perhaps you're better off breaking
it into different functions.

David


More information about the Haskell-Cafe mailing list