-
Notifications
You must be signed in to change notification settings - Fork 107
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
Use Integer in towards for halving during shrinking #397
Conversation
@@ -31,10 +31,9 @@ towards destination x = | |||
let | |||
-- Halve the operands before subtracting them so they don't overflow. | |||
-- Consider 'minBound' and 'maxBound' for a fixed sized type like 'Int64'. | |||
diff = | |||
(x `quot` 2) - (destination `quot` 2) | |||
diff = (toInteger x `quot` 2) - (toInteger destination `quot` 2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fixes the odd situation in which
2
is not representable as a number in a type. In particular this occurs in the package clash-prelude, which defines types such asUnsigned 1
where only0
and1
can be represented.
This looks reasonable, though I was wondering if we can tell the bounds of the type instead of toInteger
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so - not without adding extra type class constraints (and there is the inevitable problem that Integer
itself has no bounds)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you detect it by roundtripping 2
through fromInteger/toInteger
, the question is if GHC is smart enough to make that a constant.
@jonfowler have you got an example usage? one possibility is to use It is bad that it was hard to debug though, so it would be good to fix |
@jacobstanley this is the example:
Obviously we can use |
Also this aligns the shrinking with how |
This fixes the odd situation in which 2 is not representable as a number. In particular this occurs in the package 'clash-prelude', which defines types such as `Unsigned 1` where only 0 and 1 can be represented.
1f8972b
to
9926f9c
Compare
@jacobstanley @moodmosaic can we merge this? I don't feel it is controversial (and I would prefer not to have to use a patched version). If it is not going to get merged I will close rather than having it sit here. |
I do consider it controversial due to the use of I experimented with a few ideas and found a solution which I'm happy to merge, I'll modify this PR and push it through. towards :: Integral a => a -> a -> [a]
towards destination x =
if destination == x then
[]
-- special case for 1-bit numbers
else if destination == 0 && x == 1 then
[0]
else
-- ... snip ... |
This fixes the odd situation in which 2 is not representable as a number in a type. In particular this occurs in the package 'clash-prelude', which defines types such as
Unsigned 1
where only 0 and 1 can be represented.This is in a sense more of an issue with
clash
types not having fully validNum
instances, however it is very easy to fix here and having an error during shrinking is very difficult to debug!