How to display a time difference?

The code of the following routine is intended to indicate how long it takes for the computer to make a move. However the time is printed (as very close to zero) long before the move is made. I must be missing something about sequencing actions in the IO monad. play_move :: IORef Game_state -> IO () play_move game_state_ior = do (_, state, _) <- readIORef game_state_ior putStr "Playing AI: " start_time <- getCurrentTime let move = recommended_move state modifyIORef game_state_ior (update_interactive_from_move move) end_time <- getCurrentTime putStrLn $ show $ (diffUTCTime end_time start_time) -- Colin Adams Preston Lancashire

Colin Paul Adams wrote:
The code of the following routine is intended to indicate how long it takes for the computer to make a move. However the time is printed (as very close to zero) long before the move is made.
You are writing a thunk to the IORef. It only gets computed later on when you read the value. Try using:
readIORef game_state_ior >>= evaluate . update_interactive_from_move move >>= writeIORef game_state_ior
evaluate is in Control.Exception. -Yitz

"Yitzchak" == Yitzchak Gale
writes:
Yitzchak> Colin Paul Adams wrote: >> The code of the following routine is intended to indicate how >> long it takes for the computer to make a move. However the time >> is printed (as very close to zero) long before the move is >> made. Yitzchak> You are writing a thunk to the IORef. It only gets Yitzchak> computed later on when you read the value. Yitzchak> Try using: >> readIORef game_state_ior >>= evaluate >> . update_interactive_from_move move >>= writeIORef >> game_state_ior Yitzchak> evaluate is in Control.Exception. Still no joy with: play_move :: IORef Game_state -> IO () play_move game_state_ior = do (_, state, _) <- readIORef game_state_ior putStr "Playing AI: " start_time <- getCurrentTime let move = recommended_move state readIORef game_state_ior >>= evaluate . update_interactive_from_move move >>= writeIORef game_state_ior end_time <- getCurrentTime putStrLn $ show $ (diffUTCTime end_time start_time) -- Colin Adams Preston Lancashire

Hi Colin
The following code probably would do what I wanted to do.
play_move :: IORef Game_state -> IO ()
play_move game_state_ior = do
(_, state, _) <- readIORef game_state_ior
putStr "Playing AI: "
start_time <- getCurrentTime
let move = recommended_move state
end_time <- move `seq` (modifyIORef game_state_ior $!
update_interactive_from_move move) `seq` getCurrentTime
putStrLn $ show $ (diffUTCTime end_time start_time)
Due to the non-strictness of Haskell, the evaluation of the
expressions between start_time and end_time is deferred until there is
a need.
By using `seq` and ($!), the strictness can be forced.
Sean
On Wed, Mar 18, 2009 at 9:28 PM, Colin Paul Adams
"Yitzchak" == Yitzchak Gale
writes: Yitzchak> Colin Paul Adams wrote: >> The code of the following routine is intended to indicate how >> long it takes for the computer to make a move. However the time >> is printed (as very close to zero) long before the move is >> made.
Yitzchak> You are writing a thunk to the IORef. It only gets Yitzchak> computed later on when you read the value.
Yitzchak> Try using:
>> readIORef game_state_ior >>= evaluate >> . update_interactive_from_move move >>= writeIORef >> game_state_ior
Yitzchak> evaluate is in Control.Exception.
Still no joy with:
play_move :: IORef Game_state -> IO () play_move game_state_ior = do (_, state, _) <- readIORef game_state_ior putStr "Playing AI: " start_time <- getCurrentTime let move = recommended_move state readIORef game_state_ior >>= evaluate . update_interactive_from_move move >>= writeIORef game_state_ior end_time <- getCurrentTime putStrLn $ show $ (diffUTCTime end_time start_time)
-- Colin Adams Preston Lancashire _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
-- Sean Lee PhD Student Programming Language and Systems Research Group School of Computer Science and Engineering University of New South Wales http://www.cse.unsw.edu.au/~seanl

"Sean" == Sean Lee
writes:
Sean> Hi Colin The following code probably would do what I wanted Sean> to do. Sean> play_move :: IORef Game_state -> IO () play_move Sean> game_state_ior = do (_, state, _) <- readIORef Sean> game_state_ior putStr "Playing AI: " start_time <- Sean> getCurrentTime let move = recommended_move state end_time <- Sean> move `seq` (modifyIORef game_state_ior $! Sean> update_interactive_from_move move) `seq` getCurrentTime Sean> putStrLn $ show $ (diffUTCTime end_time start_time) Sean> Due to the non-strictness of Haskell, the evaluation of the Sean> expressions between start_time and end_time is deferred Sean> until there is a need. By using `seq` and ($!), the Sean> strictness can be forced. It certainly causes a time delay, and a non-zero time is printed, but the state doesn't get modified correctly now. ?? I will ponder Daniel's suggestion. -- Colin Adams Preston Lancashire

You get some random values? or no change at all on the state?
On Wed, Mar 18, 2009 at 9:45 PM, Colin Paul Adams
"Sean" == Sean Lee
writes: Sean> Hi Colin The following code probably would do what I wanted Sean> to do.
Sean> play_move :: IORef Game_state -> IO () play_move Sean> game_state_ior = do (_, state, _) <- readIORef Sean> game_state_ior putStr "Playing AI: " start_time <- Sean> getCurrentTime let move = recommended_move state end_time <- Sean> move `seq` (modifyIORef game_state_ior $! Sean> update_interactive_from_move move) `seq` getCurrentTime Sean> putStrLn $ show $ (diffUTCTime end_time start_time)
Sean> Due to the non-strictness of Haskell, the evaluation of the Sean> expressions between start_time and end_time is deferred Sean> until there is a need. By using `seq` and ($!), the Sean> strictness can be forced.
It certainly causes a time delay, and a non-zero time is printed, but the state doesn't get modified correctly now.
??
I will ponder Daniel's suggestion. -- Colin Adams Preston Lancashire
-- Sean Lee PhD Student Programming Language and Systems Research Group School of Computer Science and Engineering University of New South Wales http://www.cse.unsw.edu.au/~seanl

"Sean" == Sean Lee
writes:
Sean> You get some random values? or no change at all on the Sean> state? I'm not sure if the state has changed at all or not. Certainly it has not changed correctly - the move does not get made. As for Daniel's suggestion, I can't compile it because it says I need an instance of NFData for Move.Move. I'm not sure what that involves. Anyway, I don't think that evaluating move is necessarily the solution. I need to force the entire evaluation of modifyIORef. -- Colin Adams Preston Lancashire

Am Mittwoch, 18. März 2009 11:54 schrieb Sean Lee:
You get some random values? or no change at all on the state?
On Wed, Mar 18, 2009 at 9:45 PM, Colin Paul Adams
wrote: > "Sean" == Sean Lee
writes: Sean> Hi Colin The following code probably would do what I wanted Sean> to do.
Sean> play_move :: IORef Game_state -> IO () play_move Sean> game_state_ior = do (_, state, _) <- readIORef Sean> game_state_ior putStr "Playing AI: " start_time <- Sean> getCurrentTime let move = recommended_move state end_time <- Sean> move `seq` (modifyIORef game_state_ior $! Sean> update_interactive_from_move move) `seq` getCurrentTime
that should probably have been move `seq` (modifyIORef game_state_ior $! ... ) >> getCurrentTime value `seq` ioAction1 `seq` ioAction2 doesn't execute ioAction1.
Sean> putStrLn $ show $ (diffUTCTime end_time start_time)
Sean> Due to the non-strictness of Haskell, the evaluation of the Sean> expressions between start_time and end_time is deferred Sean> until there is a need. By using `seq` and ($!), the Sean> strictness can be forced.
It certainly causes a time delay, and a non-zero time is printed, but the state doesn't get modified correctly now.
??
I will ponder Daniel's suggestion. -- Colin Adams Preston Lancashire

"Daniel" == Daniel Fischer
writes:
Daniel> that should probably have been Daniel> move `seq` (modifyIORef game_state_ior $! ... ) >> Daniel> getCurrentTime Daniel> value `seq` ioAction1 `seq` ioAction2 Daniel> doesn't execute ioAction1. That did the trick! Thanks everyone. -- Colin Adams Preston Lancashire

The following code probably would do what I wanted to do.
I mean "what you wanted to do." :) -- Sean Lee PhD Student Programming Language and Systems Research Group School of Computer Science and Engineering University of New South Wales http://www.cse.unsw.edu.au/~seanl

Am Mittwoch, 18. März 2009 11:28 schrieb Colin Paul Adams:
"Yitzchak" == Yitzchak Gale
writes: Yitzchak> Colin Paul Adams wrote: >> The code of the following routine is intended to indicate how >> long it takes for the computer to make a move. However the time >> is printed (as very close to zero) long before the move is >> made.
Yitzchak> You are writing a thunk to the IORef. It only gets Yitzchak> computed later on when you read the value.
Yitzchak> Try using: >> readIORef game_state_ior >>= evaluate >> . update_interactive_from_move move >>= writeIORef >> game_state_ior
Yitzchak> evaluate is in Control.Exception.
Still no joy with:
play_move :: IORef Game_state -> IO () play_move game_state_ior = do (_, state, _) <- readIORef game_state_ior putStr "Playing AI: " start_time <- getCurrentTime let move = recommended_move state readIORef game_state_ior >>= evaluate . update_interactive_from_move move >>= writeIORef game_state_ior end_time <- getCurrentTime putStrLn $ show $ (diffUTCTime end_time start_time)
You would have to completely evaluate move. Depending on what type move is, that might require much more than what seq or evaluate do. Perhaps import Control.Parallel.Strategies let move = ... (rnf move) `seq` mofifyIORef (...) ?
participants (4)
-
Colin Paul Adams
-
Daniel Fischer
-
Sean Lee
-
Yitzchak Gale