- = let
- data_con_PN = Prel (WiredInVal data_con)
- data_con_str= snd (getOrigName data_con)
- as_needed = take (getDataConArity data_con) as_PNs
- bs_needed = take (getDataConArity data_con) bs_PNs
- con_expr = foldl App (Var data_con_PN) (map Var as_needed)
- is_nullary_con = isNullaryDataCon data_con
-
- con_qual
- = GeneratorQual
- (TuplePatIn [LitPatIn (StringLit data_con_str), d_Pat])
- (App (Var lex_PN) c_Expr)
-
- field_quals = snd (mapAccumL mk_qual d_Expr (as_needed `zip` bs_needed))
-
- read_paren_arg
- = if is_nullary_con then -- must be False (parens are surely optional)
- false_Expr
- else -- parens depend on precedence...
- OpApp a_Expr (Var gt_PN) (Lit (IntLit 9))
- in
- App (
- readParen_Expr read_paren_arg (
- Lam (mk_easy_Match [c_Pat] [] (
- ListComp (ExplicitTuple [con_expr,
- if null bs_needed then d_Expr else Var (last bs_needed)])
- (con_qual : field_quals)))
- )) (Var b_PN)
- where
- mk_qual draw_from (con_field, str_left)
- = (Var str_left, -- what to draw from down the line...
- GeneratorQual
- (TuplePatIn [VarPatIn con_field, VarPatIn str_left])
- (App (App (Var readsPrec_PN) (Lit (IntLit 10))) draw_from))
+ = HsApp (
+ readParen_Expr read_paren_arg $ HsPar $
+ HsLam (mk_easy_Match tycon_loc [c_Pat] [] $
+ HsDo ListComp stmts tycon_loc)
+ ) (HsVar b_RDR)
+ where
+ data_con_RDR = qual_orig_name data_con
+ data_con_str = occNameUserString (getOccName data_con)
+ con_arity = dataConSourceArity data_con
+ con_expr = mk_easy_App data_con_RDR as_needed
+ nullary_con = con_arity == 0
+ labels = dataConFieldLabels data_con
+ lab_fields = length labels
+ dc_nm = getName data_con
+ is_infix = isDataSymOcc (getOccName dc_nm)
+
+ as_needed = take con_arity as_RDRs
+ bs_needed
+ | is_infix = take (1 + con_arity) bs_RDRs
+ | lab_fields == 0 = take con_arity bs_RDRs
+ | otherwise = take (4*lab_fields + 1) bs_RDRs
+ -- (label, '=' and field)*n, (n-1)*',' + '{' + '}'
+
+ (as1:as2:_) = as_needed
+ (bs1:bs2:bs3:_) = bs_needed
+
+ con_qual
+ | not is_infix =
+ BindStmt
+ (TuplePatIn [LitPatIn (mkHsString data_con_str), d_Pat] Boxed)
+ (HsApp (HsVar lex_RDR) c_Expr)
+ tycon_loc
+ | otherwise =
+ BindStmt
+ (TuplePatIn [LitPatIn (mkHsString data_con_str), VarPatIn bs2] Boxed)
+ (HsApp (HsVar lex_RDR) (HsVar bs1))
+ tycon_loc
+
+
+ str_qual str res draw_from =
+ BindStmt
+ (TuplePatIn [LitPatIn (mkHsString str), VarPatIn res] Boxed)
+ (HsApp (HsVar lex_RDR) draw_from)
+ tycon_loc
+
+ str_qual_paren str res draw_from =
+ BindStmt
+ (TuplePatIn [LitPatIn (mkHsString str), VarPatIn res] Boxed)
+ (HsApp (readParen_Expr true_Expr (HsVar lex_RDR)) draw_from)
+ tycon_loc
+
+ read_label f = [rd_lab, str_qual "="]
+ -- There might be spaces between the label and '='
+ where
+ rd_lab
+ | is_op = str_qual_paren nm
+ | otherwise = str_qual nm
+
+ occ_nm = getOccName (fieldLabelName f)
+ is_op = isSymOcc occ_nm
+ nm = occNameUserString occ_nm
+
+ field_quals
+ | is_infix =
+ snd (mapAccumL mk_qual_infix
+ c_Expr
+ [ (mk_read_qual lp as1, bs1, bs2)
+ , (mk_read_qual rp as2, bs3, bs3)
+ ])
+ | lab_fields == 0 = -- common case.
+ snd (mapAccumL mk_qual
+ d_Expr
+ (zipWithEqual "as_needed"
+ (\ con_field draw_from -> (mk_read_qual 10 con_field,
+ draw_from))
+ as_needed bs_needed))
+ | otherwise =
+ snd $
+ mapAccumL mk_qual d_Expr
+ (zipEqual "bs_needed"
+ ((str_qual "{":
+ concat (
+ intersperse [str_qual ","] $
+ zipWithEqual
+ "field_quals"
+ (\ as b -> as ++ [b])
+ -- The labels
+ (map read_label labels)
+ -- The fields
+ (map (mk_read_qual 10) as_needed))) ++ [str_qual "}"])
+ bs_needed)
+
+ mk_qual_infix draw_from (f, str_left, str_left2) =
+ (HsVar str_left2, -- what to draw from down the line...
+ f str_left draw_from)
+
+ mk_qual draw_from (f, str_left) =
+ (HsVar str_left, -- what to draw from down the line...
+ f str_left draw_from)
+
+ mk_read_qual p con_field res draw_from =
+ BindStmt
+ (TuplePatIn [VarPatIn con_field, VarPatIn res] Boxed)
+ (HsApp (HsApp (HsVar readsPrec_RDR) (HsLit (HsInt p))) draw_from)
+ tycon_loc
+
+ result_expr = ExplicitTuple [con_expr, if null bs_needed
+ then d_Expr
+ else HsVar (last bs_needed)] Boxed
+
+ [lp,rp] = getLRPrecs is_infix get_fixity dc_nm
+
+ quals
+ | is_infix = let (h:t) = field_quals in (h:con_qual:t)
+ | otherwise = con_qual:field_quals
+
+ stmts = quals ++ [ResultStmt result_expr tycon_loc]
+
+ {-
+ c.f. Figure 18 in Haskell 1.1 report.
+ -}
+ paren_prec_limit
+ | not is_infix = defaultPrecedence
+ | otherwise = getPrecedence get_fixity dc_nm
+
+ read_paren_arg -- parens depend on precedence...
+ | nullary_con = false_Expr -- it's optional.
+ | otherwise = HsPar (genOpApp zz_a_Expr gt_RDR (HsLit (HsInt paren_prec_limit)))