Skip to content

Conversation

@tfausak
Copy link
Contributor

@tfausak tfausak commented Oct 2, 2019

I'm opening this PR more for discussion than anything else. Ostensibly it addresses #5, but the code as written doesn't provide any of the suggested examples.

I tried to perform a more-or-less direct translation of Go by Example: Time. Along the way I noticed several things:

  • Haskell's time library is not looking very good by comparison to Go's time package. For example, in Haskell creating a "time" (really a ZonedTime) takes 3 constructors, one function call, and one value. In Go it's a single method.

  • I used ZonedTime because it matched Go, but I think most "real" Haskell code uses UTCTime. Pretty much everything I write does, at least.

  • Go by Example has another entire page on formatting: https://gobyexample.com/time-formatting-parsing

  • Getting particular parts of the time are surprisingly challenging. For example, getting the year requires throwing away the time zone, then focusing on the day piece, then destructuring a 3-tuple. That's especially awkward because combinators for 3-tuples (like fst3) aren't super common. (On the other hand, I frequently work with times and almost never need to get just the year part of a time.)

  • Splitting apart seconds into the whole number part and the fractional part is challenging. Getting the whole number part is easy enough: truncate. But getting the fractional part would take some puzzling. Something like s - fromIntegral (truncate s) comes to mind, but that's gross.

  • ZonedTime values can't be compared directly. I think the time library does this to make you choose between comparing them as local times or as absolute times. Either way, it makes this example super annoying. (As I said before, I almost always use UTCTime.)

  • The time library doesn't provide any handy conversion functions, like for getting the length of a duration in hours. It's not hard to do the conversion manually, but it's not as nice as having a function for it.

In short, I feel like the Go example doesn't fit well into Haskell. Maybe things would be better with a different library. I think the Go example is a bit weird though, and shows off things I don't often do with time libraries.

I think the Haskell Phrasebook would be better off using some different examples. I'll spend some time tomorrow coming up with some more typical Haskell time usage.

@chris-martin
Copy link
Member

Yeah. Time is one of those topics I haven't written about yet because the library is just not something I've ever felt like I wanted to show off. Another is CSV parsing, I've been down a huge rabbit whole trying to replace cassava for the sake of the Phrasebook. If I had all the free time in the world I'd work on a new time API. Maybe based on optics?

Here's a thought that might help provide focus: It seems to me that there are two somewhat disparate use cases for time:

  • The "continuous" or "machine" view where we deal with particular moments in time, like timestamps in a log file or setting a cookie expiration date that is now plus 60 minutes.
  • The "discrete" or "human" view of time, in a particular calendar system, where we deal with facts like "halloween is every october 31" and "the meeting is at 3 o'clock eastern time"

Perhaps these are actually two fairly different subjects that deserve different pages?

@tfausak
Copy link
Contributor Author

tfausak commented Oct 3, 2019

I feel your pain with time. I briefly looked at hourglass and thyme but didn't find a compelling reason to prefer their APIs.

Those two use cases just about cover it for me. I deal with the first much more regularly, and UTCTime covers it pretty well. I'll try to come up with something that addresses that case.

@tfausak
Copy link
Contributor Author

tfausak commented Oct 3, 2019

Alright, I updated this with a vastly simplified example. I tried to stick to things that I actually do with times in Haskell. Briefly:

  • Get the current time.
  • Format a time.
  • Do some time arithmetic.
  • Do some time comparison.
  • Parse a time.
  • Find the difference between two times.
  • Get the POSIX time.
  • Convert between POSIX and "regular" times.

@chris-martin
Copy link
Member

Looks great! This'll be released under the creative commons CC BY-NC 4.0 license - Please let us know if that's okay and how you'd like to be attributed.

@tfausak
Copy link
Contributor Author

tfausak commented Oct 14, 2019

👍 That license is great!

I'm not sure what you're asking about attribution --- what are my options for attribution? Or are you looking for something else, like my preferred name and pronouns?

@chris-martin
Copy link
Member

Yeah, just name and I suppose a URL if you'd like a link to twitter or a blog or something in case just a name is ambiguous.

@tfausak
Copy link
Contributor Author

tfausak commented Oct 15, 2019

Name: Taylor Fausak
URL: https://taylor.fausak.me

@chris-martin chris-martin merged commit 6b3864e into typeclasses:master Oct 16, 2019
@tfausak tfausak deleted the patch-1 branch October 16, 2019 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants