Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

Time in Haskell

Name: Anonymous 2008-11-21 7:41

What's the best way of handling time and date values in Haskell?  I did it once, but I had to use a horrible mix of timestamps, UTC time, local time, and convert all the time:

import Data.Time.Format (formatTime)
import System.Locale (defaultTimeLocale)
import Data.Time.Clock.POSIX (getPOSIXTime, posixSecondsToUTCTime, utcTimeToPOSIXSeconds)
import Data.Time.Clock (addUTCTime, diffUTCTime, UTCTime(..))


The timestamps are for serialization to a file (or perhaps I'm using a SQLite DB).

Any nice Hackage packages or some super module that can handle everything?  Well, for my current project I only need conversion to UNIX timestamps and some kind of parsing perhaps.

Name: Anonymous 2008-11-21 10:36

The best way to handle time is to system("time");. Then write some Nomads to manipulate the value. Haskell can do I/O, right?

Name: Anonymous 2008-11-21 11:18

>>2
it's called gettimeofday

Name: Anonymous 2008-11-21 11:32

Haskell is a toy language and only usable in academic projects. (so is Scheme by the way)

Name: Anonymous 2008-11-21 12:27

>>4
as is*

Name: Anonymous 2008-11-21 12:29

>>4 is a troll and has never written a good post. (so is >>2 by the way)

Name: Anonymous 2008-11-21 13:05

Well, I settled on using readTime for parsing to UTCTime, and just used Show for serialization this time.

I don't think I'm going to do much sorting, so it probably won't hurt too much.

Name: Anonymous 2008-11-21 16:13

Retrieving the current time is not referentially transparent, therefore Haskell does not support it.

Name: Anonymous 2008-11-21 17:02

>>8
Well, you can order a Nomad to collect the current time with getCurrentTime, but there's little use for that.

Name: Anonymous 2008-11-21 20:08

That's what she said

Name: Anonymous 2008-11-21 21:28

It's actually not too hard to think about. Haskell is a functional scripting language, which means that it relies on function invokations to drive computation. A function like GetTime will always return a different value upon each invokation, so therefore Haskell cannot be used to get the current time.

Name: Anonymous 2008-11-21 21:45

>>11
That makes sense. All this time, I was imagining the getChar action returning a different value when it is called.

Name: Anonymous 2008-11-21 22:07

What? HIBT? getChar and getPOSIXTime return the same value every time, try it.

Name: Anonymous 2008-11-21 22:15

>>13
I currently don't have Glorious Haskell installed, but that doesn't sound right.

Name: Anonymous 2008-11-22 4:20

>>12
Oh no, the values getChar returns are already predefined.  Haskell contains a model of the entire universe which it can use to make deterministic choices in indeterminate situations.

Name: Anonymous 2008-11-22 5:48

>>15
Haskell contains a monad of the entire universe
fixed

Name: Anonymous 2008-11-22 8:25

>>13
Prelude Data.Time.Clock.POSIX> getPOSIXTime
1227360245.609375s
Prelude Data.Time.Clock.POSIX> getPOSIXTime
1227360246.515625s
Prelude Data.Time.Clock.POSIX> getPOSIXTime
1227360246.90625s
Prelude Data.Time.Clock.POSIX> getPOSIXTime
1227360247.34375s

(Y|I)HBT

Name: Anonymous 2008-11-22 9:43

>>17
Get that shit the fuck out of my pure functional programming model!!!!!

Name: Anonymous 2008-11-22 10:14

>>17
I'm not really into that whole FP think, but from what I've read, I think getPOSIXTime returns the same monad every time, and your interpreter just executes it.

Name: Anonymous 2008-11-22 11:01

Time is an input, get over it.

The worst part is that the delay is variable so it isn't as clean or repeatable.

Think of timeOf f, where f is a function and timeOf just runs it, regardless of value ( alarm bells should be going off already ), and produces how many seconds it took to run.

Suddenly giving the same value into the function doesn't return the same results. It is worse than rand.

Measuring time functionally is sorta funny.

Name: Anonymous 2008-11-22 11:34

>>17
getPOSIXTime returns an IO PosixTime. It will return that same IO PosixTime every time it is called, and so it is referentially transparent and has no side-effects. It is only when that IO PosixTime is passed to something that performs IO (such as whatever calls main (note that main itself still does not `do' IO) or unsafePerformIO or GHCI's evaluator) that the IO can be performed. You can't perform IO from within the program itself (with the exception of System.IO.Unsafe).

Prelude> let x = getLine in x >>= \ x1 -> x >>= \ x2 -> print (x1 ++ " " ++ x2)
Hello
World!
"Hello World!"


This expression didn't actually evaluate to "Hello World!", it evaluated to an IO (), and GHCI will tell you as much with :t.

Prelude> let readTwo = (let x = getLine in x >>= \ x1 -> x >>= \ x2 -> print (x1 ++ " " ++ x2))
Prelude> readTwo
A
B
"A B"
Prelude> readTwo
C
D
"C D"
Prelude>


Furthermore, the IO nomad ensures that anything that performs IO is `tagged' with the IO nomad and can only be performed by one of the aforementioned methods, thus ensuring that the computations are performed in the correct order, and only once. This is obviously something that the imperative style does easily. However, one could argue that the nomadic style does this better. Consider the snippet printf("ABC") + printf("DEF"). The order of evaluation here is not defined, and while this is a simple situation, more complex and subtle ones could easily arise[citation needed]. The IO nomad disallows such things — it is necessary to use combinators such as >>, >>=, and derived combinators such as sequence, mapM_, etc.

Thus, any function which performs IO returns the same value every time (for the same arguments); it simply returns an IO a which describes the IO actions to perform (which are of type RealWorld# -> RealWorld#, I believe) and what to do with the result. But these actual actions are delayed until the IO-performer performs them. Thanks to the non-strict evaluation, this can be done as the structure of IO actions and callbacks is produced, which is why IO happens as the program runs, and does not all get performed at the end of the program[clarify].

At no point (except using unsafePerformIO, Debug.trace and the like, but these are debugging tools and not meant for structuring your program) is it possible to replace an expression with its result and unwittingly modify the behaviour of the program (for example, in a C-like language, replacing printf("NOMADS") with just 6 changes the behaviour). Note that it is possible to introduce functions which are not referentially transparent by improperly annotating foreign imported functions.

(As far as I'm aware, the do-notation doesn't really `count' as far as that definition goes, since it's just syntactic sugar for >>= and >>. Replacing getPOSIXTime in a do expression with the IO PosixTime that getPOSIXTime returns would not modify the program's behaviour.)

(And of course, in Haskell, the IO constructor is not available to programs. It is not possible to construct the IO actions yourself, which is why it is necessary to use getPOSIXTime and friends.)

That's how I understand it, anyway. I think I repeated myself a few times here, and possibly repeated myself a bit, but hopefully I got my point across, whatever my point is.[not funny]

tl;dr: Nomads are magic.

Name: Anonymous 2008-11-22 16:37

Man haskell is confusing.

Name: Anonymous 2008-11-22 17:02

Elegance can be quite confusing to the ignorant.

Name: Anonymous 2008-11-22 17:23

Haskell is great for Factorial.

Name: Anonymous 2008-11-22 19:04

>>24
fact x = if x == 1 then 1 else x * fact (x-1) ??

Name: Anonymous 2008-11-22 19:11

>>22
Hasn't read SICP

Name: Anonymous 2008-11-22 19:27

>>26
Doesn't understand HASKELL and tried to conceal it by desperately pointing out that others didn't read SICP.

Name: Anonymous 2008-11-22 19:47

http://arcanux.org/lambdacats.html
An accurate description of haskell.

Name: Anonymous 2011-02-02 23:49

Don't change these.
Name: Email:
Entire Thread Thread List