summaryrefslogtreecommitdiff
path: root/libraries/template-haskell
diff options
context:
space:
mode:
authorJakob Bruenker <jakob.bruenker@gmail.com>2022-03-21 00:14:25 +0100
committerJakob Bruenker <jakob.bruenker@gmail.com>2022-04-01 20:31:08 +0200
commit32070e6c2e1b4b7c32530a9566fe14543791f9a6 (patch)
treef0913ef2a69fd660542723ec07240167dbd37961 /libraries/template-haskell
parentd85c7dcb7c457efc23b20ac8f4e4ae88bae5b050 (diff)
downloadhaskell-32070e6c2e1b4b7c32530a9566fe14543791f9a6.tar.gz
Implement \cases (Proposal 302)
This commit implements proposal 302: \cases - Multi-way lambda expressions. This adds a new expression heralded by \cases, which works exactly like \case, but can match multiple apats instead of a single pat. Updates submodule haddock to support the ITlcases token. Closes #20768
Diffstat (limited to 'libraries/template-haskell')
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Lib.hs6
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs5
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Ppr.hs16
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Syntax.hs2
4 files changed, 22 insertions, 7 deletions
diff --git a/libraries/template-haskell/Language/Haskell/TH/Lib.hs b/libraries/template-haskell/Language/Haskell/TH/Lib.hs
index 42fa6cd501..8e8e41df2f 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Lib.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Lib.hs
@@ -42,9 +42,9 @@ module Language.Haskell.TH.Lib (
-- *** Expressions
dyn, varE, unboundVarE, labelE, implicitParamVarE, conE, litE, staticE,
appE, appTypeE, uInfixE, parensE, infixE, infixApp, sectionL, sectionR,
- lamE, lam1E, lamCaseE, tupE, unboxedTupE, unboxedSumE, condE, multiIfE,
- letE, caseE, appsE, listE, sigE, recConE, recUpdE, stringE, fieldExp,
- getFieldE, projectionE,
+ lamE, lam1E, lamCaseE, lamCasesE, tupE, unboxedTupE, unboxedSumE, condE,
+ multiIfE, letE, caseE, appsE, listE, sigE, recConE, recUpdE, stringE,
+ fieldExp, getFieldE, projectionE,
-- **** Ranges
fromE, fromThenE, fromToE, fromThenToE,
diff --git a/libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs b/libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs
index e960f35bb3..5d2a32d761 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs
@@ -300,9 +300,14 @@ lamE ps e = do ps' <- sequenceA ps
lam1E :: Quote m => m Pat -> m Exp -> m Exp
lam1E p e = lamE [p] e
+-- | Lambda-case (@\case@)
lamCaseE :: Quote m => [m Match] -> m Exp
lamCaseE ms = LamCaseE <$> sequenceA ms
+-- | Lambda-cases (@\cases@)
+lamCasesE :: Quote m => [m Clause] -> m Exp
+lamCasesE ms = LamCasesE <$> sequenceA ms
+
tupE :: Quote m => [Maybe (m Exp)] -> m Exp
tupE es = do { es1 <- traverse sequenceA es; pure (TupE es1)}
diff --git a/libraries/template-haskell/Language/Haskell/TH/Ppr.hs b/libraries/template-haskell/Language/Haskell/TH/Ppr.hs
index 51e89fda2a..e2af99339f 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Ppr.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Ppr.hs
@@ -154,8 +154,11 @@ pprExp _ (InfixE me1 op me2) = parens $ pprMaybeExp noPrec me1
pprExp i (LamE [] e) = pprExp i e -- #13856
pprExp i (LamE ps e) = parensIf (i > noPrec) $ char '\\' <> hsep (map (pprPat appPrec) ps)
<+> text "->" <+> ppr e
-pprExp i (LamCaseE ms) = parensIf (i > noPrec)
- $ text "\\case" $$ braces (semiSep ms)
+pprExp i (LamCaseE ms)
+ = parensIf (i > noPrec) $ text "\\case" $$ braces (semiSep ms)
+pprExp i (LamCasesE ms)
+ = parensIf (i > noPrec) $ text "\\cases" $$ braces (semi_sep ms)
+ where semi_sep = sep . punctuate semi . map (pprClause False)
pprExp i (TupE es)
| [Just e] <- es
= pprExp i (ConE (tupleDataName 1) `AppE` e)
@@ -270,6 +273,12 @@ pprBody eq body = case body of
| otherwise = arrow
------------------------------
+pprClause :: Bool -> Clause -> Doc
+pprClause eqDoc (Clause ps rhs ds)
+ = hsep (map (pprPat appPrec) ps) <+> pprBody eqDoc rhs
+ $$ where_clause ds
+
+------------------------------
instance Ppr Lit where
ppr = pprLit noPrec
@@ -652,8 +661,7 @@ instance Ppr RuleBndr where
------------------------------
instance Ppr Clause where
- ppr (Clause ps rhs ds) = hsep (map (pprPat appPrec) ps) <+> pprBody True rhs
- $$ where_clause ds
+ ppr = pprClause True
------------------------------
instance Ppr Con where
diff --git a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
index 08d2ea41bf..fdf2e6bf39 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
@@ -2242,6 +2242,7 @@ type FieldPat = (Name,Pat)
data Match = Match Pat Body [Dec] -- ^ @case e of { pat -> body where decs }@
deriving( Show, Eq, Ord, Data, Generic )
+
data Clause = Clause [Pat] Body [Dec]
-- ^ @f { p1 p2 = body where decs }@
deriving( Show, Eq, Ord, Data, Generic )
@@ -2273,6 +2274,7 @@ data Exp
-- See "Language.Haskell.TH.Syntax#infix"
| LamE [Pat] Exp -- ^ @{ \\ p1 p2 -> e }@
| LamCaseE [Match] -- ^ @{ \\case m1; m2 }@
+ | LamCasesE [Clause] -- ^ @{ \\cases m1; m2 }@
| TupE [Maybe Exp] -- ^ @{ (e1,e2) } @
--
-- The 'Maybe' is necessary for handling