- gunfold_bind = mk_FunMonoBind tycon_loc gunfold_RDR (map gunfold_eqn data_cons ++ [catch_all])
- gunfold_eqn con = ([VarPat k_RDR, VarPat z_RDR, wildPat,
- ConPatIn constr_RDR (PrefixCon [LitPat (mk_constr_string con)])],
- apN (dataConSourceArity con)
- (\e -> HsVar k_RDR `HsApp` e)
- (z_Expr `HsApp` HsVar (getRdrName con)))
- catch_all = ([wildPat, wildPat, VarPat e_RDR, wildPat], HsVar e_RDR)
- mk_constr_string con = mkHsString (occNameUserString (getOccName con))
-
- ------------ conOf
- conOf_bind = mk_FunMonoBind tycon_loc conOf_RDR (map conOf_eqn data_cons)
- conOf_eqn con = ([mkWildConPat con], mk_constr con)
-
- ------------ consOf
- consOf_bind = mk_easy_FunMonoBind tycon_loc consOf_RDR [wildPat] []
- (ExplicitList placeHolderType (map mk_constr data_cons))
- mk_constr con = HsVar constr_RDR `HsApp` (HsLit (mk_constr_string con))
-
-
-apN :: Int -> (a -> a) -> a -> a
-apN 0 k z = z
-apN n k z = apN (n-1) k (k z)
+ gunfold_bind = mk_FunBind tycon_loc
+ gunfold_RDR
+ [([k_Pat, z_Pat, if one_constr then nlWildPat else c_Pat],
+ gunfold_rhs)]
+
+ gunfold_rhs
+ | one_constr = mk_unfold_rhs (head data_cons) -- No need for case
+ | otherwise = nlHsCase (nlHsVar conIndex_RDR `nlHsApp` c_Expr)
+ (map gunfold_alt data_cons)
+
+ gunfold_alt dc = mkSimpleHsAlt (mk_unfold_pat dc) (mk_unfold_rhs dc)
+ mk_unfold_rhs dc = foldr nlHsApp
+ (nlHsVar z_RDR `nlHsApp` nlHsVar (getRdrName dc))
+ (replicate (dataConSourceArity dc) (nlHsVar k_RDR))
+
+ mk_unfold_pat dc -- Last one is a wild-pat, to avoid
+ -- redundant test, and annoying warning
+ | tag-fIRST_TAG == n_cons-1 = nlWildPat -- Last constructor
+ | otherwise = nlConPat intDataCon_RDR [nlLitPat (HsIntPrim (toInteger tag))]
+ where
+ tag = dataConTag dc
+
+ ------------ toConstr
+ toCon_bind = mk_FunBind tycon_loc toConstr_RDR (map to_con_eqn data_cons)
+ to_con_eqn dc = ([nlWildConPat dc], nlHsVar (mk_constr_name dc))
+
+ ------------ dataTypeOf
+ dataTypeOf_bind = mk_easy_FunBind
+ tycon_loc
+ dataTypeOf_RDR
+ [nlWildPat]
+ (nlHsVar data_type_name)
+
+ ------------ $dT
+
+ data_type_name = mkDerivedRdrName tycon_name mkDataTOcc
+ datatype_bind = mkVarBind
+ tycon_loc
+ data_type_name
+ ( nlHsVar mkDataType_RDR
+ `nlHsApp` nlHsLit (mkHsString (showSDoc (ppr tycon)))
+ `nlHsApp` nlList constrs
+ )
+ constrs = [nlHsVar (mk_constr_name con) | con <- data_cons]
+
+
+ ------------ $cT1 etc
+ mk_constr_name con = mkDerivedRdrName (dataConName con) mkDataCOcc
+ mk_con_bind dc = mkVarBind
+ tycon_loc
+ (mk_constr_name dc)
+ (nlHsApps mkConstr_RDR (constr_args dc))
+ constr_args dc =
+ [ -- nlHsIntLit (toInteger (dataConTag dc)), -- Tag
+ nlHsVar data_type_name, -- DataType
+ nlHsLit (mkHsString (occNameString dc_occ)), -- String name
+ nlList labels, -- Field labels
+ nlHsVar fixity] -- Fixity
+ where
+ labels = map (nlHsLit . mkHsString . getOccString)
+ (dataConFieldLabels dc)
+ dc_occ = getOccName dc
+ is_infix = isDataSymOcc dc_occ
+ fixity | is_infix = infix_RDR
+ | otherwise = prefix_RDR
+
+gfoldl_RDR = varQual_RDR gENERICS FSLIT("gfoldl")
+gunfold_RDR = varQual_RDR gENERICS FSLIT("gunfold")
+toConstr_RDR = varQual_RDR gENERICS FSLIT("toConstr")
+dataTypeOf_RDR = varQual_RDR gENERICS FSLIT("dataTypeOf")
+mkConstr_RDR = varQual_RDR gENERICS FSLIT("mkConstr")
+mkDataType_RDR = varQual_RDR gENERICS FSLIT("mkDataType")
+conIndex_RDR = varQual_RDR gENERICS FSLIT("constrIndex")
+prefix_RDR = dataQual_RDR gENERICS FSLIT("Prefix")
+infix_RDR = dataQual_RDR gENERICS FSLIT("Infix")