Skip to content

Conversation

@Hyalunar
Copy link

@Hyalunar Hyalunar commented Oct 2, 2025

I wrote this code sometime and figured I might contribute it back after polishing it up.

Creates a newtype called Circular and implements the Enum typeclass for it.
All operations using the Enum instance are now circular, none call error (something that often annoyed me), but some may produce infinite lists, when given the right arguments.

I also added some tests, but I'm not very versed with unit testing.
Feel free to suggest more test cases, I could also add QuickCheck tests.

If desired, I could also imagine adding more methods like already present (csucc and cpred), which just wrap to Circular internally.

@memowe
Copy link
Owner

memowe commented Oct 14, 2025

Thank you very much for your contribution, I like your work! 🚀 I just checked it out locally and start reading it in detail, let's work together on this.

Maybe let's discuss some things first:

I could also add QuickCheck tests.

What property tests do you suggest?

I could also imagine adding more methods like already present (csucc and cpred), which just wrap to Circular internally.

As there's no runtime penalty for using newtypes, I think it makes sense to go all in use it internally for csucc/cpred. What other functions to you suggest?

Using an old ubuntu version for runners prevented runners from
picking up our workflows. Fixed in main.
@Hyalunar
Copy link
Author

What property tests do you suggest?

Sadly, I don't have Ideas for meaningful property based testing, since the Enum must be defined in the source code which would not allow for much randomness.
Sorry if this was confusing, I wanted to advertise my ability to add QuickCheck tests if you wanted some.

As there's no runtime penalty for using newtypes, I think it makes sense to go all in use it internally for csucc/cpred. What other functions to you suggest?

I thought about the other enum functions which would then do the wrapping for you, namely:

  • toEnum: using mod on maxBound
  • fromEnum, this one is not very useful, but could be included for completeness
  • enumFrom
  • enumFromThen
  • enumFromTo
  • enumFromThenTo

For consistency with the current API, these could all be prefixed with c.

-- Beware: this alters the behaviour of some functions, producing infinite lists (because of circularity)

newtype Circular a = Circular a
deriving (Show, Eq, Ord, Bounded)
Copy link
Owner

Choose a reason for hiding this comment

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

Actually, I don't know if we should derive Bounded here as the whole point of this newtype is to go beyond boundaries.

Copy link
Owner

Choose a reason for hiding this comment

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

I tried to address this in 2ca189e

@memowe memowe marked this pull request as draft October 15, 2025 15:56
as the whole point of it to go beyond boundaries.
Only the sky is the limit.
@memowe
Copy link
Owner

memowe commented Oct 16, 2025

When/If this is ready to join,

  • move GHC extensions to cabal file

@Hyalunar
Copy link
Author

I have moved the Language Extensions to circular-enum.cabal. As a Bonus: It seems like this is compatible with MicroHS.

@memowe
Copy link
Owner

memowe commented Nov 10, 2025

I'm working on it. :) Stay tuned. :)

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.

2 participants