summaryrefslogtreecommitdiff
path: root/compiler/deSugar/DsListComp.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/deSugar/DsListComp.hs')
-rw-r--r--compiler/deSugar/DsListComp.hs118
1 files changed, 62 insertions, 56 deletions
diff --git a/compiler/deSugar/DsListComp.hs b/compiler/deSugar/DsListComp.hs
index 4d11fa21b8..d835995857 100644
--- a/compiler/deSugar/DsListComp.hs
+++ b/compiler/deSugar/DsListComp.hs
@@ -81,11 +81,13 @@ dsListComp lquals res_ty = do
-- and the type of the elements that it outputs (tuples of binders)
dsInnerListComp :: (ParStmtBlock Id Id) -> DsM (CoreExpr, Type)
dsInnerListComp (ParStmtBlock stmts bndrs _)
- = do { expr <- dsListComp (stmts ++ [noLoc $ mkLastStmt (mkBigLHsVarTupId bndrs)])
+ = do { let bndrs_tuple_type = mkBigCoreVarTupTy bndrs
+
+ -- really use original bndrs below!
+ ; expr <- dsListComp (stmts ++ [noLoc $ mkLastStmt (mkBigLHsVarTupId bndrs)])
(mkListTy bndrs_tuple_type)
+
; return (expr, bndrs_tuple_type) }
- where
- bndrs_tuple_type = mkBigCoreVarTupTy bndrs
-- This function factors out commonality between the desugaring strategies for GroupStmt.
-- Given such a statement it gives you back an expression representing how to compute the transformed
@@ -94,47 +96,50 @@ dsTransStmt :: ExprStmt Id -> DsM (CoreExpr, LPat Id)
dsTransStmt (TransStmt { trS_form = form, trS_stmts = stmts, trS_bndrs = binderMap
, trS_by = by, trS_using = using }) = do
let (from_bndrs, to_bndrs) = unzip binderMap
- from_bndrs_tys = map idType from_bndrs
+
+ let from_bndrs_tys = map idType from_bndrs
to_bndrs_tys = map idType to_bndrs
+
to_bndrs_tup_ty = mkBigCoreTupTy to_bndrs_tys
-- Desugar an inner comprehension which outputs a list of tuples of the "from" binders
- (expr, from_tup_ty) <- dsInnerListComp (ParStmtBlock stmts from_bndrs noSyntaxExpr)
+ (expr', from_tup_ty) <- dsInnerListComp (ParStmtBlock stmts from_bndrs noSyntaxExpr)
-- Work out what arguments should be supplied to that expression: i.e. is an extraction
-- function required? If so, create that desugared function and add to arguments
usingExpr' <- dsLExpr using
- usingArgs <- case by of
- Nothing -> return [expr]
- Just by_e -> do { by_e' <- dsLExpr by_e
- ; lam <- matchTuple from_bndrs by_e'
- ; return [lam, expr] }
+ usingArgs' <- case by of
+ Nothing -> return [expr']
+ Just by_e -> do { by_e' <- dsLExpr by_e
+ ; lam' <- matchTuple from_bndrs by_e'
+ ; return [lam', expr'] }
-- Create an unzip function for the appropriate arity and element types and find "map"
- unzip_stuff <- mkUnzipBind form from_bndrs_tys
+ unzip_stuff' <- mkUnzipBind form from_bndrs_tys
map_id <- dsLookupGlobalId mapName
-- Generate the expressions to build the grouped list
let -- First we apply the grouping function to the inner list
- inner_list_expr = mkApps usingExpr' usingArgs
+ inner_list_expr' = mkApps usingExpr' usingArgs'
-- Then we map our "unzip" across it to turn the lists of tuples into tuples of lists
-- We make sure we instantiate the type variable "a" to be a list of "from" tuples and
-- the "b" to be a tuple of "to" lists!
-- Then finally we bind the unzip function around that expression
- bound_unzipped_inner_list_expr
- = case unzip_stuff of
- Nothing -> inner_list_expr
- Just (unzip_fn, unzip_rhs) -> Let (Rec [(unzip_fn, unzip_rhs)]) $
- mkApps (Var map_id) $
- [ Type (mkListTy from_tup_ty)
- , Type to_bndrs_tup_ty
- , Var unzip_fn
- , inner_list_expr]
+ bound_unzipped_inner_list_expr'
+ = case unzip_stuff' of
+ Nothing -> inner_list_expr'
+ Just (unzip_fn', unzip_rhs') ->
+ Let (Rec [(unzip_fn', unzip_rhs')]) $
+ mkApps (Var map_id) $
+ [ Type (mkListTy from_tup_ty)
+ , Type to_bndrs_tup_ty
+ , Var unzip_fn'
+ , inner_list_expr' ]
-- Build a pattern that ensures the consumer binds into the NEW binders,
-- which hold lists rather than single values
- let pat = mkBigLHsVarPatTupId to_bndrs
- return (bound_unzipped_inner_list_expr, pat)
+ let pat = mkBigLHsVarPatTupId to_bndrs -- NB: no '!
+ return (bound_unzipped_inner_list_expr', pat)
dsTransStmt _ = panic "dsTransStmt: Not given a TransStmt"
@@ -260,13 +265,12 @@ deBindComp :: OutPat Id
-> CoreExpr
-> DsM (Expr Id)
deBindComp pat core_list1 quals core_list2 = do
- let
- u3_ty@u1_ty = exprType core_list1 -- two names, same thing
+ let u3_ty@u1_ty = exprType core_list1 -- two names, same thing
-- u1_ty is a [alpha] type, and u2_ty = alpha
- u2_ty = hsLPatType pat
+ let u2_ty = hsLPatType pat
- res_ty = exprType core_list2
+ let res_ty = exprType core_list2
h_ty = u1_ty `mkFunTy` res_ty
[h, u1, u2, u3] <- newSysLocalsDs [h_ty, u1_ty, u2_ty, u3_ty]
@@ -309,9 +313,9 @@ TE[ e | p <- l , q ] c n = let
\end{verbatim}
-}
-dfListComp :: Id -> Id -- 'c' and 'n'
- -> [ExprStmt Id] -- the rest of the qual's
- -> DsM CoreExpr
+dfListComp :: Id -> Id -- 'c' and 'n'
+ -> [ExprStmt Id] -- the rest of the qual's
+ -> DsM CoreExpr
dfListComp _ _ [] = panic "dfListComp"
@@ -355,7 +359,7 @@ dfBindComp :: Id -> Id -- 'c' and 'n'
dfBindComp c_id n_id (pat, core_list1) quals = do
-- find the required type
let x_ty = hsLPatType pat
- b_ty = idType n_id
+ let b_ty = idType n_id
-- create some new local id's
[b, x] <- newSysLocalsDs [b_ty, x_ty]
@@ -570,7 +574,7 @@ dePArrComp (BindStmt p e _ _ : qs) pa cea = do
--
dePArrComp (LetStmt (L _ ds) : qs) pa cea = do
mapP <- dsDPHBuiltin mapPVar
- let xs = collectLocalBinders ds
+ let xs = collectLocalBinders ds
ty'cea = parrElemType cea
v <- newSysLocalDs ty'cea
clet <- dsLocalBinds ds (mkCoreTup (map Var xs))
@@ -629,10 +633,10 @@ dePArrParComp qss quals = do
-- generate Core corresponding to `\p -> e'
--
-deLambda :: Type -- type of the argument
- -> LPat Id -- argument pattern
- -> LHsExpr Id -- body
- -> DsM (CoreExpr, Type)
+deLambda :: Type -- type of the argument
+ -> LPat Id -- argument pattern
+ -> LHsExpr Id -- body
+ -> DsM (CoreExpr, Type)
deLambda ty p e =
mkLambda ty p =<< dsLExpr e
@@ -720,37 +724,39 @@ dsMcStmt (TransStmt { trS_stmts = stmts, trS_bndrs = bndrs
, trS_ret = return_op, trS_bind = bind_op
, trS_fmap = fmap_op, trS_form = form }) stmts_rest
= do { let (from_bndrs, to_bndrs) = unzip bndrs
- from_bndr_tys = map idType from_bndrs -- Types ty
+
+ ; let from_bndr_tys = map idType from_bndrs -- Types ty
+
-- Desugar an inner comprehension which outputs a list of tuples of the "from" binders
- ; expr <- dsInnerMonadComp stmts from_bndrs return_op
+ ; expr' <- dsInnerMonadComp stmts from_bndrs return_op
-- Work out what arguments should be supplied to that expression: i.e. is an extraction
-- function required? If so, create that desugared function and add to arguments
; usingExpr' <- dsLExpr using
- ; usingArgs <- case by of
- Nothing -> return [expr]
- Just by_e -> do { by_e' <- dsLExpr by_e
- ; lam <- matchTuple from_bndrs by_e'
- ; return [lam, expr] }
+ ; usingArgs' <- case by of
+ Nothing -> return [expr']
+ Just by_e -> do { by_e' <- dsLExpr by_e
+ ; lam' <- matchTuple from_bndrs by_e'
+ ; return [lam', expr'] }
-- Generate the expressions to build the grouped list
-- Build a pattern that ensures the consumer binds into the NEW binders,
-- which hold monads rather than single values
; bind_op' <- dsExpr bind_op
- ; let bind_ty = exprType bind_op' -- m2 (n (a,b,c)) -> (n (a,b,c) -> r1) -> r2
- n_tup_ty = funArgTy $ funArgTy $ funResultTy bind_ty -- n (a,b,c)
- tup_n_ty = mkBigCoreVarTupTy to_bndrs
-
- ; body <- dsMcStmts stmts_rest
- ; n_tup_var <- newSysLocalDs n_tup_ty
- ; tup_n_var <- newSysLocalDs tup_n_ty
- ; tup_n_expr <- mkMcUnzipM form fmap_op n_tup_var from_bndr_tys
- ; us <- newUniqueSupply
- ; let rhs' = mkApps usingExpr' usingArgs
- body' = mkTupleCase us to_bndrs body tup_n_var tup_n_expr
-
- ; return (mkApps bind_op' [rhs', Lam n_tup_var body']) }
+ ; let bind_ty' = exprType bind_op' -- m2 (n (a,b,c)) -> (n (a,b,c) -> r1) -> r2
+ n_tup_ty' = funArgTy $ funArgTy $ funResultTy bind_ty' -- n (a,b,c)
+ tup_n_ty' = mkBigCoreVarTupTy to_bndrs
+
+ ; body <- dsMcStmts stmts_rest
+ ; n_tup_var' <- newSysLocalDs n_tup_ty'
+ ; tup_n_var' <- newSysLocalDs tup_n_ty'
+ ; tup_n_expr' <- mkMcUnzipM form fmap_op n_tup_var' from_bndr_tys
+ ; us <- newUniqueSupply
+ ; let rhs' = mkApps usingExpr' usingArgs'
+ body' = mkTupleCase us to_bndrs body tup_n_var' tup_n_expr'
+
+ ; return (mkApps bind_op' [rhs', Lam n_tup_var' body']) }
-- Parallel statements. Use `Control.Monad.Zip.mzip` to zip parallel
-- statements, for example: