You are not logged in.

#1 2008-12-18 23:57:51

timetrap
Member
From: Here and There
Registered: 2008-06-05
Posts: 342
Website

haskell loops

I know haskell has no loops. (or shouldn't) so how do I get a function to  . . . loop.

Here's what I have so far:

import Time

timerClock      :: ClockTime -> ClockTime
timerClock t    =  addToClockTime (TimeDiff 0 0 0 0 0 15 0) t

main = do x <- getClockTime
          if x < timerClock x
                then putStrLn "Done!"
                else putStrLn "."

I have the basic code working. I want to add 15 mins to the current time, then I want to check and see if the current time is equal to the 15 mins in the future that I specified.

I just cannot figure out how to make it run more than once.

Functions, functions everywhere! And not one to loop.

Last edited by timetrap (2008-12-18 23:59:27)

Offline

#2 2008-12-19 00:31:34

Xyne
Administrator/PM
Registered: 2008-08-03
Posts: 6,963
Website

Re: haskell loops

Here's a suggestion for using recursion. There are probably a few syntax errors in this (I've only just begun learning Haskell, and very lazily):

import Time

timerClock      :: ClockTime -> ClockTime
timerClock t    =  addToClockTime (TimeDiff 0 0 0 0 0 15 0) t


test t = do x <- getClockTime
            if x < t
                then putStrLn "Done!"
                else putStrLn "."
                     test t

main = do t <- timerClock
          test t

I wasn't sure of how to set up the typeclass for "test" (ClockTime -> ?) or if multiple commands can just be separated by newlines. Also, if there's a "sleep" function, add that to the else clause in test so that it doesn't waste CPU cycles.

Also, I used the code in your post, but I suspect that you want "x > t", not "x < t" in the conditional.

Last edited by Xyne (2008-12-19 00:32:57)


My Arch Linux StuffForum EtiquetteCommunity Ethos - Arch is not for everyone

Offline

#3 2008-12-19 02:12:19

alexsuraci
Member
Registered: 2008-09-27
Posts: 15

Re: haskell loops

Untested, but I think there are a couple problems in Xyne's, so I fixed them:

import Time

timerClock      :: ClockTime -> ClockTime
timerClock t    =  addToClockTime (TimeDiff 0 0 0 0 0 15 0) t


test :: ClockTime -> IO ()
test t = do x <- getClockTime
            if x < t
                then putStrLn "Done!"
                else do putStrLn "."
                        test t
                        return ()

main = do t <- timerClock
          test t

Offline

#4 2008-12-19 02:19:30

Xyne
Administrator/PM
Registered: 2008-08-03
Posts: 6,963
Website

Re: haskell loops

Thanks alexsuraci, I had no idea what the classtype should be. Can you explain why you've added "return ()" to "test", and why it's only in the "else" clause? (just trying to learn)


My Arch Linux StuffForum EtiquetteCommunity Ethos - Arch is not for everyone

Offline

#5 2008-12-19 03:49:49

alexsuraci
Member
Registered: 2008-09-27
Posts: 15

Re: haskell loops

Xyne: Sure.

`main` has a type of `main :: IO ()`, and the last thing you have it call is "test t". Because of that, "test t" should always return the type `IO ()`.

Adding "return ()" there ensures that it returns an IO (). In the "then" clause, putStrLn already returns IO () (hence why `main = putStrLn "hi"` works), but because the "else" clause is where you do the recursion, I figured I'd throw that in for good measure. I'm not entirely certain if it's necessary.

On second thought, it probably isn't necessary. If you think about how the recursion steps through things, it'll go like this:

putStrLn "." (call self) -> putStrLn "." (call self) -> putStrLn "." (call self) -> putStrLn "Done!". That would ultimately return IO (), from the `putStrLn "Done!"`, but not because of the "." since that's not the last thing in the `do`.

So, assuming it reaches "Done!" eventually, it should work fine without the "return ()" line. It doesn't do any harm leaving it there, though. It's just a bit redundant. smile

Last edited by alexsuraci (2008-12-19 03:52:12)

Offline

#6 2008-12-19 04:54:22

Xyne
Administrator/PM
Registered: 2008-08-03
Posts: 6,963
Website

Re: haskell loops

@alexsuraci

Thanks for the clear and thorough explanation. smile


My Arch Linux StuffForum EtiquetteCommunity Ethos - Arch is not for everyone

Offline

#7 2008-12-19 08:58:18

ddaedalus
Member
Registered: 2008-01-14
Posts: 54

Re: haskell loops

import Time

loop :: ClockTime -> ClockTime -> IO ()
loop s c | (tdSec $ diffClockTimes c s) > 0 = return ()
loop s c = do
        putStr "."
        t <- getClockTime
        loop s t

main = do
        t <- getClockTime
        loop (addToClockTime (TimeDiff 0 0 0 0 0 5 0) t) t
        putStrLn "Done."

Last edited by ddaedalus (2008-12-19 11:03:54)

Offline

#8 2008-12-19 10:08:19

timetrap
Member
From: Here and There
Registered: 2008-06-05
Posts: 342
Website

Re: haskell loops

Thanks! Learning Haskell is learning how to program again . . .

Offline

#9 2008-12-19 10:51:08

ddaedalus
Member
Registered: 2008-01-14
Posts: 54

Re: haskell loops

timetrap wrote:

Learning Haskell is learning how to program again . . .

Learning Haskell is learning to program for the first time.
When i found out about Haskell I understood that my past experiences are absolutely void in comparison to what lies ahead of me.

Offline

#10 2009-01-01 03:11:26

steveklabnik
Member
Registered: 2009-01-01
Posts: 7
Website

Re: haskell loops

ddaedalus wrote:
import Time

loop :: ClockTime -> ClockTime -> IO ()
loop s c | (tdSec $ diffClockTimes c s) > 0 = return ()
loop s c = do
        putStr "."
        t <- getClockTime
        loop s t

main = do
        t <- getClockTime
        loop (addToClockTime (TimeDiff 0 0 0 0 0 5 0) t) t
        putStrLn "Done."

This.

The key with Haskell is to not think about 'How would I program that?' The key is to think, "What do I want?"

As programmers, we're used to thinking about what we want our program to do, applying the tools that we've learned to get the computer to do what we want, and then writing out the code. At least, that's what I do. But with Haskell, often the solution is much more elegant than you'd expect. Loops aren't in the language because they're not neccesary. The code for loop says "put a . and get a new time, then call myself. over and over. that is, until the difference is positive.

However, while expressive, I feel like this isn't even the best possible way of doing it. Check out the 'until' function...

Offline

Board footer

Powered by FluxBB