summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian McKenna <brian@brianmckenna.org>2014-12-02 17:53:38 +0100
committerHerbert Valerio Riedel <hvr@gnu.org>2014-12-02 17:54:50 +0100
commit7c38e985aa211ca44039c6d1db9fa13690749c59 (patch)
tree1c97a63cd1e023644bc97c8144ed348dab6dffb9
parent6b063ef2a1f68290b51778a38e9b89b6fec5e170 (diff)
downloadhaskell-7c38e985aa211ca44039c6d1db9fa13690749c59.tar.gz
Make `read . show = id` for Data.Fixed (fix #9240)
The QuickCheck property now succeeds: prop :: Fixed B7 -> Bool prop a = read (show a) == a This changes the Show instance for Fixed to round up, rather than down when calculating a digit. This needs to happen because Read also rounds down: data B7 instance HasResolution B7 where resolution _ = 128 1 / 128 = 0.0078125 read "0.007" = (0.000 :: Fixed B7) Here is an example of the change to Show: showFixed False (0.009 :: Fixed B7) -- Broken: "0.007" -- Fixed: "0.008" And now Read can continue to round down: read "0.008" = (0.0078125 :: Fixed B7) Reviewed By: hvr, ekmett Differential Revision: https://phabricator.haskell.org/D547
-rw-r--r--libraries/base/Data/Fixed.hs4
-rw-r--r--libraries/base/changelog.md2
-rw-r--r--libraries/base/tests/data-fixed-show-read.hs7
-rw-r--r--libraries/base/tests/data-fixed-show-read.stdout2
4 files changed, 14 insertions, 1 deletions
diff --git a/libraries/base/Data/Fixed.hs b/libraries/base/Data/Fixed.hs
index 068eec5f12..f12a0e496d 100644
--- a/libraries/base/Data/Fixed.hs
+++ b/libraries/base/Data/Fixed.hs
@@ -143,7 +143,9 @@ showFixed chopTrailingZeros fa@(MkFixed a) = (show i) ++ (withDot (showIntegerZe
-- enough digits to be unambiguous
digits = ceiling (logBase 10 (fromInteger res) :: Double)
maxnum = 10 ^ digits
- fracNum = div (d * maxnum) res
+ -- read floors, so show must ceil for `read . show = id` to hold. See #9240
+ fracNum = divCeil (d * maxnum) res
+ divCeil x y = (x + y - 1) `div` y
instance (HasResolution a) => Show (Fixed a) where
show = showFixed False
diff --git a/libraries/base/changelog.md b/libraries/base/changelog.md
index 07c91a34aa..ef3e9ae95c 100644
--- a/libraries/base/changelog.md
+++ b/libraries/base/changelog.md
@@ -128,6 +128,8 @@
together with a new exception `AllocationLimitExceeded`.
+ * Make `read . show = id` for `Data.Fixed` (#9240)
+
## 4.7.0.2 *Dec 2014*
* Bundled with GHC 7.8.4
diff --git a/libraries/base/tests/data-fixed-show-read.hs b/libraries/base/tests/data-fixed-show-read.hs
index 349f639f2c..7e947f466e 100644
--- a/libraries/base/tests/data-fixed-show-read.hs
+++ b/libraries/base/tests/data-fixed-show-read.hs
@@ -3,6 +3,11 @@ module Main (main) where
import Data.Fixed
+data B7
+
+instance HasResolution B7 where
+ resolution _ = 128
+
main :: IO ()
main = do doit 38.001
doit 38.009
@@ -14,6 +19,8 @@ main = do doit 38.001
doit (-38.01)
doit (-38.09)
print (read "-38" :: Centi)
+ print (read "0.008" :: Fixed B7)
+ print (read "-0.008" :: Fixed B7)
doit :: Centi -> IO ()
doit c = do let s = show c
diff --git a/libraries/base/tests/data-fixed-show-read.stdout b/libraries/base/tests/data-fixed-show-read.stdout
index 0e5d7caef5..4abb2d9676 100644
--- a/libraries/base/tests/data-fixed-show-read.stdout
+++ b/libraries/base/tests/data-fixed-show-read.stdout
@@ -16,3 +16,5 @@
-38.09
-38.09
-38.00
+0.008
+-0.008