Skip to content

more efficient genBoundedEnum #33

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

Closed
wants to merge 1 commit into from

Conversation

matthewleon
Copy link
Contributor

Should reduce time and space complexity to that of chooseInt for most BoundedEnum instances.

Should reduce time and space complexity to that of chooseInt for most
BoundedEnum instances.
bottomInt = fromEnum (bottom :: a)
enumRange = topInt - bottomInt
in if enumRange == unwrap (cardinality :: Cardinality a)
then unsafePartial $ fromJust <<< toEnum <$> chooseInt bottomInt topInt
Copy link
Contributor

Choose a reason for hiding this comment

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

This actually is unsafe though, if the Enum instance is bad, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

If you excluded bottom, and added it back in fromMaybe, this could be safe though.

Copy link
Contributor

Choose a reason for hiding this comment

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

But then it might be harder to ensure this is uniformly distributed :(

let topInt = fromEnum (top :: a)
bottomInt = fromEnum (bottom :: a)
enumRange = topInt - bottomInt
in if enumRange == unwrap (cardinality :: Cardinality a)
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this always be the case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My idea here was that if the Enum instance is bad, this test will fail. If it's good, then the test passes and the following line is safe. I'll rethink this... I'm probably missing something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I see what you mean... A bad Enum instance could just be lying about its Cardinality. Argh.

@matthewleon
Copy link
Contributor Author

I definitely see your points, above. At the same time, I feel like this is pretty useful for the majority of well-behaved Enum instances. Should this perhaps be instead farmed out into an unsafeGenBoundedEnum, perhaps with a Partial constraint?

@paf31
Copy link
Contributor

paf31 commented Nov 22, 2017

If there is a need for this for performance reasons, then I would be okay with putting it in an unsafe module. Note it really is unsafe, because nothing in the Enum laws requires the values to map to contiguous integers.

@matthewleon
Copy link
Contributor Author

Yes, this makes sense. I do feel that because generating random things is something that can often happen in a loop, it makes some sense to make this version available somewhere, with clear documentation explaining its lack of safety. I'll take another pass at this soon.

@matthewleon
Copy link
Contributor Author

I'm closing this. I think there is a more principled way to do this.

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