Restore invariant in `Data (Ratio a)` instance
authorHerbert Valerio Riedel <hvr@gnu.org>
Wed, 21 Jan 2015 07:21:36 +0000 (08:21 +0100)
committerHerbert Valerio Riedel <hvr@gnu.org>
Thu, 22 Jan 2015 21:36:24 +0000 (22:36 +0100)
(2nd attempt, this time leaving the `Constr` using `":%"`)

The Data instance for `Ratio` just uses the raw `:%` constructor and
doesn't check that the result is reduced to normal form.

The fix is to add back the `Integral` constraint on the Data
instance (which was dropped in c409b6f30373535) and to use `%` rather
than `:%` in the `gfoldl` and `gunfold` implementation.

This restores the invariant and matches the behavior of "virtual
constructors" we've used to patch up such problems elsewhere.

This addresses #10011

Reviewed By: ekmett, austin

Differential Revision: https://phabricator.haskell.org/D625

libraries/base/Data/Data.hs
libraries/base/changelog.md

index dce610b..6961b25 100644 (file)
@@ -1064,10 +1064,10 @@ ratioConstr = mkConstr ratioDataType ":%" [] Infix
 ratioDataType :: DataType
 ratioDataType = mkDataType "GHC.Real.Ratio" [ratioConstr]
 
-instance Data a => Data (Ratio a) where
-  gfoldl k z (a :% b) = z (:%) `k` a `k` b
+instance (Data a, Integral a) => Data (Ratio a) where
+  gfoldl k z (a :% b) = z (%) `k` a `k` b
   toConstr _ = ratioConstr
-  gunfold k z c | constrIndex c == 1 = k (k (z (:%)))
+  gunfold k z c | constrIndex c == 1 = k (k (z (%)))
   gunfold _ _ _ = error "Data.Data.gunfold(Ratio)"
   dataTypeOf _  = ratioDataType
 
index 83ae5e4..0d7ebcf 100644 (file)
 
   * Add `callocArray` and `callocArray0` to `Foreign.Marshal.Array`. (#9859)
 
+  * Restore invariant in `Data (Ratio a)` instance (#10011)
+
 ## 4.7.0.2  *Dec 2014*
 
   * Bundled with GHC 7.8.4