Why does reading a constantly changing file happen in two and a half seconds, giving the same value?

I just wrote this liner in Haskell to find out how much bandwidth I use per second:

>>> import Control.Monad (forever)
>>> import Control.Concurrent (threadDelay) -- microseconds; 10^6Ξs = 1s
>>> let f = "/sys/class/net/wlan0/statistics/rx_bytes" in forever $ readFile f >>= \a -> threadDelay (10^6) >> readFile f >>= \b -> print (read b - read a)
0
0
0
0
0
0
0
0
0

But he always says 0. I drew a parallel equivalent line of code in Bash that shows that the file did change during this time:

$ f=/sys/class/net/wlan0/statistics/rx_bytes; while true; do a=`cat $f`; sleep 1; echo $((`cat $f`-a)); done
98
98
2132
3178
230
306
98
98
729

Why doesn't Haskell see the change?

+4
source share
1 answer

readFilelazy, that is, in fact, does not gain access to the data in the file until you evaluate the variable associated with it: in your case read a. At this time, the stream delay has already passed, and you are evaluating the file in the same state as b!

:

forever $ do
   a <- fmap read $ readFile f
   a `seq` threadDelay (10^6)
   b <- fmap read $ readFile f
   print $ b - a
+11

Source: https://habr.com/ru/post/1524625/


All Articles