until and Time

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

until and Time

Steve Klabnik-2
Hello everyone. I have a quick question about Time.

I was talking about Haskell on the Arch Linux forums today, and someone was
trying to put together code that would print a series of periods for, say, 5
minutes. I felt like using 'until' would be the most correct way of going
about it, but when I tried to do it...


import Time

makeLater      :: ClockTime -> ClockTime
makeLater t    =  addToClockTime (TimeDiff 0 0 0 0 0 5 0) t

updateTime :: ClockTime -> ClockTime
updateTime t = t

main = do
  start <- getClockTime
  until ((==) $ makeLater start) (updateTime) start
  putStrLn "done"

Now, updateTime isn't correct. And this wouldn't print any periods. But GHC
is giving me errors:

$ runhaskell temp.hs

temp.hs:11:2:
    Couldn't match expected type `IO t'
           against inferred type `ClockTime'
    In the expression:
        until ((==) $ makeLater start) (updateTime) start
    In a 'do' expression:
        until ((==) $ makeLater start) (updateTime) start
    In the expression:
        do start <- getClockTime
           until ((==) $ makeLater start) (updateTime) start
           putStrLn "done"

I'm not sure where IO t is coming from at all. Am I even on the right track?
How would you write this code?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20081231/9f9a42d1/attachment-0001.htm
Reply | Threaded
Open this post in threaded view
|

until and Time

Daniel Fischer-4
Am Donnerstag, 1. Januar 2009 04:18 schrieb Steve Klabnik:

> Hello everyone. I have a quick question about Time.
>
> I was talking about Haskell on the Arch Linux forums today, and someone was
> trying to put together code that would print a series of periods for, say,
> 5 minutes. I felt like using 'until' would be the most correct way of going
> about it, but when I tried to do it...
>
>
> import Time
>
> makeLater      :: ClockTime -> ClockTime
> makeLater t    =  addToClockTime (TimeDiff 0 0 0 0 0 5 0) t
>
> updateTime :: ClockTime -> ClockTime
> updateTime t = t
>
> main = do
>   start <- getClockTime
>   until ((==) $ makeLater start) (updateTime) start
>   putStrLn "done"
>
> Now, updateTime isn't correct. And this wouldn't print any periods. But GHC
> is giving me errors:
>
> $ runhaskell temp.hs
>
> temp.hs:11:2:
>     Couldn't match expected type `IO t'
>            against inferred type `ClockTime'
>     In the expression:
>         until ((==) $ makeLater start) (updateTime) start
>     In a 'do' expression:
>         until ((==) $ makeLater start) (updateTime) start
>     In the expression:
>         do start <- getClockTime
>            until ((==) $ makeLater start) (updateTime) start
>            putStrLn "done"
>
> I'm not sure where IO t is coming from at all. Am I even on the right
> track? How would you write this code?

Since it appears as a statement in the main do-block, ghc expects "until ..."
to have type IO t. But as
Prelude> :t until
until :: (a -> Bool) -> (a -> a) -> a -> a

until ((==) $ makeLater start) (updateTime) start

actually has type ClockTime, so can't appear as a statement in a do-block,
that's what ghc tells you.

Since you want a timeout, which involves IO, you must do something in IO.
You can define a general control structure (I'm sure that is already defined
somewhere, but I can't be bothered to hoogle it now)

untilM :: (Monad m) => (a -> m Bool) -> (a -> m a) -> a -> m a
untilM test action value = do
        stop <- test value
        if stop then return value
          else do
            newval <- action value
            untilM test action newval

and then

isLaterThan :: ClockTime -> IO Bool
isLaterThan end = do
        now <- getClockTime
        return (end < now)


main = do
        start <- getClockTime
        let end = addToClockTime (TimeDiff 0 0 0 0 0 5 0) start
        untilM (\_ -> isLaterThan end) (\_ -> putChar '.') ()
        putStr "\n"


Reply | Threaded
Open this post in threaded view
|

until and Time

Steve Klabnik-2
Ahh. Thank you. That makes much more sense now.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20090101/29d59a85/attachment.htm