module DsListComp ( dsListComp, dsPArrComp ) where
--- XXX This define is a bit of a hack, and should be done more nicely
-#define FAST_STRING_NOT_NEEDED 1
#include "HsVersions.h"
import {-# SOURCE #-} DsExpr ( dsLExpr, dsLocalBinds )
import HsSyn
import TcHsSyn
import CoreSyn
+import MkCore
import DsMonad -- the monadery used in the desugarer
import DsUtils
import DynFlags
import CoreUtils
-import Var
+import Id
import Type
-import TysPrim
import TysWiredIn
import Match
import PrelNames
dflags <- getDOptsDs
let quals = map unLoc lquals
- if not (dopt Opt_RewriteRules dflags) || dopt Opt_IgnoreInterfacePragmas dflags
+ if not (dopt Opt_EnableRewriteRules dflags) || dopt Opt_IgnoreInterfacePragmas dflags
-- Either rules are switched off, or we are ignoring what there are;
-- Either way foldr/build won't happen, so use the more efficient
-- Wadler-style desugaring
|| isParallelComp quals
-- Foldr-style desugaring can't handle parallel list comprehensions
then deListComp quals body (mkNilExpr elt_ty)
- else do -- Foldr/build should be enabled, so desugar
- -- into foldrs and builds
- [n_tyvar] <- newTyVarsDs [alphaTyVar]
-
- let n_ty = mkTyVarTy n_tyvar
- c_ty = mkFunTys [elt_ty, n_ty] n_ty
- [c, n] <- newSysLocalsDs [c_ty, n_ty]
-
- result <- dfListComp c n quals body
- build_id <- dsLookupGlobalId buildName
- return (Var build_id `App` Type elt_ty `App` mkLams [n_tyvar, c, n] result)
+ else mkBuildExpr elt_ty (\(c, _) (n, _) -> dfListComp c n quals body)
+ -- Foldr/build should be enabled, so desugar
+ -- into foldrs and builds
where
-- We must test for ParStmt anywhere, not just at the head, because an extension
pat core_rest (Var b)
-- now build the outermost foldr, and return
- foldr_id <- dsLookupGlobalId foldrName
- return (Var foldr_id `App` Type x_ty
- `App` Type b_ty
- `App` mkLams [x, b] core_expr
- `App` Var n_id
- `App` core_list1)
-
+ mkFoldrExpr x_ty b_ty (mkLams [x, b] core_expr) (Var n_id) core_list1
\end{code}
%************************************************************************
unzip_fn <- newSysLocalDs unzip_fn_ty
- foldr_id <- dsLookupGlobalId foldrName
[us1, us2] <- sequence [newUniqueSupply, newUniqueSupply]
let nil_tuple = mkBigCoreTup (map mkNilExpr elt_tys)
folder_body_outer_case = mkTupleCase us2 xs folder_body_inner_case ax (Var ax)
folder_body = mkLams [ax, axs] folder_body_outer_case
- unzip_body = mkApps (Var foldr_id) [Type elt_tuple_ty, Type elt_list_tuple_ty, folder_body, nil_tuple, Var ys]
- unzip_body_saturated = mkLams [ys] unzip_body
-
- return (unzip_fn, unzip_body_saturated)
+ unzip_body <- mkFoldrExpr elt_tuple_ty elt_list_tuple_ty folder_body nil_tuple (Var ys)
+ return (unzip_fn, mkLams [ys] unzip_body)
where
elt_tuple_ty = mkBigCoreTupTy elt_tys
elt_tuple_list_ty = mkListTy elt_tuple_ty
-> DsM CoreExpr
dsPArrComp [ParStmt qss] body _ = -- parallel comprehension
dePArrParComp qss body
+
+-- Special case for simple generators:
+--
+-- <<[:e' | p <- e, qs:]>> = <<[: e' | qs :]>> p e
+--
+-- if matching again p cannot fail, or else
+--
+-- <<[:e' | p <- e, qs:]>> =
+-- <<[:e' | qs:]>> p (filterP (\x -> case x of {p -> True; _ -> False}) e)
+--
+dsPArrComp (BindStmt p e _ _ : qs) body _ = do
+ filterP <- dsLookupGlobalId filterPName
+ ce <- dsLExpr e
+ let ety'ce = parrElemType ce
+ false = Var falseDataConId
+ true = Var trueDataConId
+ v <- newSysLocalDs ety'ce
+ pred <- matchSimply (Var v) (StmtCtxt PArrComp) p true false
+ let gen | isIrrefutableHsPat p = ce
+ | otherwise = mkApps (Var filterP) [Type ety'ce, mkLams [v] pred, ce]
+ dePArrComp qs body p gen
+
dsPArrComp qs body _ = do -- no ParStmt in `qs'
sglP <- dsLookupGlobalId singletonPName
let unitArray = mkApps (Var sglP) [Type unitTy, mkCoreTup []]
- dePArrComp qs body (mkLHsPatTup []) unitArray
+ dePArrComp qs body (noLoc $ WildPat unitTy) unitArray
v <- newSysLocalDs ty'cea
clet <- dsLocalBinds ds (mkCoreTup (map Var xs))
let'v <- newSysLocalDs (exprType clet)
- let projBody = mkDsLet (NonRec let'v clet) $
+ let projBody = mkCoreLet (NonRec let'v clet) $
mkCoreTup [Var v, Var let'v]
errTy = exprType projBody
errMsg = "DsListComp.dePArrComp: internal error!"