Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Month of year type #246

Closed
wants to merge 3 commits into from

Conversation

NorfairKing
Copy link

This PR exists to show that I'm happy to do the work necessary to resolve #134

Current status: The code compiles, but with warnings and failing tests.

At this point I want to acknowledge that resolving #134 is a nontrivial amount of work.
The internals of the time library become slightly more complex in order to prevent footguns and runtime errors for users.
There are also minor performance improvements in some places and regressions in others.

I understand that, as the maintainer @AshleyYakeley, you are in your right to close this PR without comment or even ignore it entirely.
However, I would strongly urge you to consider how many footguns and runtime issues this change can prevent, in the interest of the library's users.

I also understand that this PR will likely cause some ruffled feathers, so I want to make it extra clear that I mean no offense toward anyone who disagrees with my technical viewpoint on this matter.
I only want to make an effort towards a less dangerous technical solution.

where
YearMonth y my = MkMonth $ (y * 12) + toInteger (pred $ clip 1 12 my)
YearMonth y my = MkMonth $ (y * 12) + toInteger (monthOfYearIndex (pred my))

fromYearMonthValid :: Year -> MonthOfYear -> Maybe Month
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left this function for backward compatibility even though it is now no longer necessary.


-- | The length of a given month in the Gregorian or Julian calendars.
-- First arg is leap year flag.
monthLength :: Bool -> MonthOfYear -> DayOfMonth
monthLength isLeap month' = monthLength' isLeap (clip 1 12 month')
monthLength isLeap month = case month of
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function may be slightly more performant now.

instance Arbitrary MonthOfYear where
arbitrary = choose (1, 12) `suchThatMap` parseMonthOfYearIndex
shrink January = []
shrink _ = [January]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More accurate shrinking may be in order.

@AshleyYakeley
Copy link
Member

#134 is already closed.

@AshleyYakeley
Copy link
Member

AshleyYakeley commented Nov 2, 2023

This PR would make it easier to work with months-of-year as names, while more difficult to work with them as numbers. I believe the latter is the more common case, so a net negative.

@AshleyYakeley
Copy link
Member

The "footgun" in the current design (using a month-of-year outside the range 1..12) is already obvious to anyone using the library, and is mirrored by "footguns" for day-of-month, hour-of-day, etc., which this PR does not (and of course should not) address.

@AshleyYakeley
Copy link
Member

Finally, this PR would break a lot of existing code.

@NorfairKing
Copy link
Author

NorfairKing commented Nov 2, 2023

@AshleyYakeley you make an excellent point wrt breakage.

I'd be happy to close this and make a new PR with only the following

  • Turn all occurrences of the MonthOfYear synonym back into Int
  • Add the parseMonthOfYearIndex and monthOfYearIndex functions.
  • Make a new MonthOfYear sum type

That way backward incompatibility is minimised because fromGregorian/toGregorian remain unchanged, and users don't need to define their own MonthOfYear type that then clashes in the namespace with the type synonym.

Would such a PR be more acceptable?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MonthOfYear data type
2 participants