Opened 7 years ago

Closed 7 years ago

#2782 closed bug (fixed)

Data instance for ratio changed, now incompatible

Reported by: NeilMitchell Owned by:
Priority: normal Milestone:
Component: libraries/base Version: 6.10.1
Keywords: Cc: ndmitchell@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Test Case:
Blocked By: Blocking:
Related Tickets: Differential Revisions:

Description

Using the following code:

import Data.Generics -- import Data.Data on 6.10
import Data.Ratio

-- data  (Integral a)      => Ratio a = !a :% !a  deriving (Eq)

u = undefined :: Ratio Integer

ctr t = head $ dataTypeConstrs $ dataTypeOf t

ctr2 t = length $ gmapQ (const undefined) $ asTypeOf (fromConstr $ ctr t) t

test = ctr2 u

Under GHC 6.8.2 I get the answer 0, under GHC 6.10.1 I get the answer "undefined". Both are wrong, but at least the GHC 6.8.2 one works enough for me to use it. So there are a couple of issues here:

1) fromConstr = fromConstrB undefined in Data.Data is a really bad idea - instead of undefined error "Data.Data.fromConstr" would be a million times better. It took 3 hours to even figure out what library was causing the undefined in a 80 module program! base was not my first guess :-)

2) Ratio used to have a workable fromConstr, now it doesn't. Before it gave the wrong answer. It's all to do with the strictness annotations on :%. The new version means I can't use Uniplate with Haskell Source Exts, which is a really big shame. I have no idea what the fix is.

Change History (3)

comment:1 Changed 7 years ago by NeilMitchell

  • Cc ndmitchell@… added

comment:2 Changed 7 years ago by claus

I'm not sure I follow: neither strictness nor fromConstr have changed (I think?). The only change I'm aware of is that the Data instance for Ratio used to be inconsistent (treating the type as abstract for gfoldl and as concrete for gunfold), while it now treats the type as concrete for both directions.

Your example tries to map a query over the subterms of an undefined Ratio, relying on the old half-abstract behaviour for not actually looking for subterms. Whereas with the new instance gmapQ will look for subterms and fail. The old behaviour can be restored by making the abstract handling of Ratio explicit:

ctr2 t = length $ (gmapQ (const undefined) `extQ` ratio) $ asTypeOf (fromConstr $ ctr t) t

test = ctr2 u

ratio :: Ratio Integer -> [a]
ratio _ = []

Now we get 0 from both versions of ghc.

comment:3 Changed 7 years ago by igloo

  • Component changed from Compiler to libraries/base
  • difficulty set to Unknown
  • Resolution set to fixed
  • Status changed from new to closed

I've changed the undefined as you suggest. If you want the actual behaviour changed, then can you please file a proposal? http://www.haskell.org/haskellwiki/Library_submissions

Note: See TracTickets for help on using tickets.