[commit: ghc] wip/T10858: Fix my horribly broken âimprovedâ Ord deriving code (c07fd1d)
git at git.haskell.org
git at git.haskell.org
Wed Sep 9 07:46:57 UTC 2015
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/T10858
Link : http://ghc.haskell.org/trac/ghc/changeset/c07fd1dc37aae27a118fafd482dab52ba4946cb3/ghc
>---------------------------------------------------------------
commit c07fd1dc37aae27a118fafd482dab52ba4946cb3
Author: Joachim Breitner <mail at joachim-breitner.de>
Date: Wed Sep 9 09:47:41 2015 +0200
Fix my horribly broken “improved” Ord deriving code
but still do something smaller than previously, using the thenCmp
operator.
(JFTR: This is a commit on a wip/ branch, so do not worry about the
unpolished commit messages :-))
>---------------------------------------------------------------
c07fd1dc37aae27a118fafd482dab52ba4946cb3
compiler/typecheck/TcGenDeriv.hs | 48 +++++++++++++++++++++-------------------
1 file changed, 25 insertions(+), 23 deletions(-)
diff --git a/compiler/typecheck/TcGenDeriv.hs b/compiler/typecheck/TcGenDeriv.hs
index 5e694a9..4d7c48b 100644
--- a/compiler/typecheck/TcGenDeriv.hs
+++ b/compiler/typecheck/TcGenDeriv.hs
@@ -372,16 +372,6 @@ gtResult OrdGE = true_Expr
gtResult OrdGT = true_Expr
------------
-combineResult :: OrdOp -> RdrName
--- Knowing a1 ? b2 and a2 ? b2?,
--- how do we combine that to obtain (a1,a2) ? (b1,b2)
-combineResult OrdCompare = thenCmp_RDR
-combineResult OrdLT = or_RDR
-combineResult OrdLE = and_RDR
-combineResult OrdGE = and_RDR
-combineResult OrdGT = or_RDR
-
-------------
gen_Ord_binds :: SrcSpan -> TyCon -> (LHsBinds RdrName, BagDerivStuff)
gen_Ord_binds loc tycon
| null tycon_data_cons -- No data-cons => invoke bale-out case
@@ -499,20 +489,32 @@ mkCompareFields :: TyCon -> OrdOp -> [Type] -> LHsExpr RdrName
-- Generates nested comparisons for (a1,a2...) against (b1,b2,...)
-- where the ai,bi have the given types
mkCompareFields tycon op tys
- = go tys as_RDRs bs_RDRs
+ = go (zip3 tys as_RDRs bs_RDRs)
where
- -- Build a chain of calls to the current operator for each field, combined
- -- with the appropriate combinator from combineResult.
- go [] _ _ = eqResult op
- go [ty] (a:_) (b:_) = mk_compare ty a b
- go (ty:tys) (a:as) (b:bs) = genOpApp (mk_compare ty a b) (combineResult op) (go tys as bs)
- go _ _ _ = panic "mkCompareFields"
-
- mk_compare ty a b
- | isUnLiftedType ty
- = unliftedOrdOp tycon ty op a b
- | otherwise
- = genOpApp (nlHsVar a) (ordMethRdr op) (nlHsVar b)
+ -- With one field, we can simply use the current operator.
+ -- With two fields, we have use `compare` on the first.
+ -- With more than two fields, we use `compare` on all but the first, and
+ -- combine the result with thenCmp.
+ go [] = eqResult op
+ go [arg] = mk_op arg
+ go args
+ | OrdCompare <- op
+ = mk_compares args
+ | otherwise
+ = nlHsCase (nlHsPar (mk_compares (init args)))
+ [mkSimpleHsAlt (nlNullaryConPat ltTag_RDR) (ltResult op),
+ mkSimpleHsAlt (nlNullaryConPat eqTag_RDR) (mk_op (last args)),
+ mkSimpleHsAlt (nlNullaryConPat gtTag_RDR) (gtResult op)]
+
+ mk_op (ty, a, b)
+ | isUnLiftedType ty = unliftedOrdOp tycon ty op a b
+ | otherwise = genOpApp (nlHsVar a) (ordMethRdr op) (nlHsVar b)
+
+ mk_compares args = foldr1 (`genOpApp` thenCmp_RDR) (map mk_compare args)
+
+ mk_compare (ty, a, b)
+ | isUnLiftedType ty = unliftedOrdOp tycon ty (OrdCompare) a b
+ | otherwise = genOpApp (nlHsVar a) (compare_RDR) (nlHsVar b)
unliftedOrdOp :: TyCon -> Type -> OrdOp -> RdrName -> RdrName -> LHsExpr RdrName
unliftedOrdOp tycon ty op a b
More information about the ghc-commits
mailing list