-
Notifications
You must be signed in to change notification settings - Fork 52
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
Please provide instance for (Enum a, Bounded a) for Random #21
Comments
What instance do you have in mind, |
I thought there was a most specific instance rule? The instance would just pick a random constructor from those available (range known by Bounded), evenly distributed among all the enumerations (defined by Enum). The implementation is not hard, I just haven't written it or opened a PR or anything yet. Essentially, the best case scenario would be if the compiler could derive Random, but it can't, so having an Enum/Bounded instance is the closest thing to it, since it will derive those automatically for you. |
This would prevent any user derived instances. If you manufactured a newtype for just giving this instance, that might be more tenable. But even then, this also implicitly assumes a uniform distribution is always the correct default, and I'm not sure if thats true! (Or that every Bounded instance is a properly lawful one, which I'd hope but wouldnt want to impose.) The analogous monoids induced by |
I kind of got the impression that the Random typeclass implied uniform, but no? At least, all the existing instances seem to be uniform, and I can't think of a case where you wouldn't just plug something on top of the linear distr to give the different distribution you need. |
A reasonable default instance is: instance Random Action where
randomR (a, b) g =
case randomR (fromEnum a, fromEnum b) g of
(x, g') -> (toEnum x, g')
random g = randomR (minBound, maxBound) g It's tricky boilerplate that would be easy to get wrong and that you just copy-paste. Maybe Random could export: defaultBoundedEnumRandomR :: (Bounded a, Enum a, RandomGen g) => (a, a) -> g -> (a, g)
defaultBoundedEnumRandomR (a, b) g =
case randomR (fromEnum a, fromEnum b) g of
(x, g') -> (toEnum x, g')
defaultBoundedEnumRandom :: (Bounded a, Enum a, RandomGen g) => g -> (a, g)
defaultBoundedEnumRandom g = defaultBoundedEnumRandomR (minBound, maxBound) g And then users could simply do: instance Random Action where
randomR = defaultBoundedEnumRandomR
random = defaultBoundedEnumRandom |
exporting some default methods might be good. interesting idea! |
These would also be useful to use directly (rather than in a Random instance): suppose you import a type that is an instance of Bounded and Enum but not Random, and you don't want to define an orphan Random instance. So, we could just leave The first one doesn't require |
This would be really nice to have. |
Ah yes, another +1 on this .. it’s 3 year’s old, I had forgotten all about it . |
Is PR accepted ? |
I’m working on a new release. Stay tuned.
…On Mon, Oct 30, 2017 at 8:40 PM k.vanberendonck ***@***.***> wrote:
Is PR accepted ?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#21 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAAQwmrleSss9xVAF--nbAk2yXlTUfL9ks5sxmx0gaJpZM4CqzBl>
.
|
I'm not convinced that sprinkling a couple of However, I would not particularly oppose a PR, introducing |
I think we should introduce newtype wrapper which allows to derive Uniform/UniformRange instances using DerivingVia newtype UniformEnum a = UniformEnum a
instance Enum a => UniformRange (UnniformEnum a) where
...
instance (Bounded a, Enum a) => Uniform (UnniformEnum a) where
...
data RGB = R | G | B
deriving (Enum.Bounded)
deriving Uniform via UniformEnum RGB |
@Shimuuar that looks good to me! |
Closing as done in #104. Feel free to reopen if there is a specific motivation to use this feature via old |
It would be really nice to be able to do something like this:
The implementation for
(Enum a, Bounded a) =>
can cheat a little to get a valid range (psuedo, for randomRIO since it's easier/shorter to show):Note the usage of the underlying instance for
Int
to select a constructor.It would have been magical if we could have just a
Enum a =>
instance, but I can't think of a way to do it.The text was updated successfully, but these errors were encountered: