It's all regrettably delicate, but I think the simplest thing to do is to write integer-simple using either case expressions direct, or function definitions that trivially desugar into case expressions. Ie not this:
xorDigits None (!ds) = ds xorDigits (!ds) None = ds xorDigits (Some w1 ds1) (Some w2 ds2) = Some (w1 `xor#` w2) (xorDigits ds1 ds2) but rather xorDigits None None = None xorDigits None ds@(Some _) = ds xorDigits ds@(Some _) None = ds xorDigits (Some ..) (Some..) = as before better to keep it simple than try to make the desugarer a bit more clever .. but then it'll fall over at the next complication. Simon | -----Original Message----- | From: [email protected] [mailto:[email protected]] On Behalf Of Max | Bolingbroke | Sent: 01 August 2011 08:55 | To: Simon Peyton-Jones | Cc: Malcolm Wallace; Chris Dornan; [email protected] | Subject: Re: integer-simple | | On 1 August 2011 08:09, Simon Peyton-Jones <[email protected]> wrote: | > I'm guessing here, but I bet I know what's going on. If integer-simple uses | > inexhaustive pattern matching, GHC will generate calls to 'patError' for the | > missing cases. That in turn generates a dependency on base, which is where | > patError is defined. | | I checked this and you are right. If you build with -O0 you can see | the failure that Chris describes, because GHC does not eliminate some | of the patErrors. They come from (e.g.) xorDigits, whose tidied Core | is: | | {{{ | Rec { | xorDigits_raD | :: GHC.Integer.Type.Digits | -> GHC.Integer.Type.Digits -> GHC.Integer.Type.Digits | [GblId, Arity=2] | xorDigits_raD = | \ (ds_dh8 :: GHC.Integer.Type.Digits) | (ds1_afu :: GHC.Integer.Type.Digits) -> | let { | fail_dh9 | :: GHC.Prim.State# GHC.Prim.RealWorld -> GHC.Integer.Type.Digits | [LclId, Arity=1] | fail_dh9 = | \ _ -> | Control.Exception.Base.patError | @ GHC.Integer.Type.Digits | "libraries/integer-simple/GHC/Integer.hs:(734,1)-(736,79)|function | GHC.Integer.xorDigits" } in | case ds_dh8 of wild_X1j { | GHC.Integer.Type.Some ipv_snV ipv1_snW -> | case ds1_afu of wild1_X1r { | GHC.Integer.Type.Some ipv2_snZ ipv3_so0 -> | case wild_X1j of _ { | GHC.Integer.Type.Some w1_afw ds2_afx -> | case wild1_X1r of _ { | GHC.Integer.Type.Some w2_afy ds3_afz -> | case xorDigits_raD ds2_afx ds3_afz of tpl1_X5 { __DEFAULT -> | GHC.Integer.Type.Some (GHC.Prim.xor# w1_afw w2_afy) tpl1_X5 | }; | GHC.Integer.Type.None -> fail_dh9 GHC.Prim.realWorld# | }; | GHC.Integer.Type.None -> fail_dh9 GHC.Prim.realWorld# | }; | GHC.Integer.Type.None -> wild_X1j | }; | GHC.Integer.Type.None -> ds1_afu | } | end Rec } | }}} | | They seem to originate from using bang patterns in the definitions: | | {{{ | xorDigits :: Digits -> Digits -> Digits | xorDigits None (!ds) = ds | xorDigits (!ds) None = ds | xorDigits (Some w1 ds1) (Some w2 ds2) = Some (w1 `xor#` w2) (xorDigits ds1 | ds2) | }}} | | Maybe the pattern match desugarer needs to be modified to see that the | pattern (!x) is irrefutable? | | In the short term the workaround is to build the libraries with at least -O. | | Max _______________________________________________ Cvs-ghc mailing list [email protected] http://www.haskell.org/mailman/listinfo/cvs-ghc
