summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDr. ERDI Gergo <gergo@erdi.hu>2014-07-06 23:49:43 +0800
committerDr. ERDI Gergo <gergo@erdi.hu>2014-07-29 11:34:41 +0200
commit0279a7d327a3b962ffa93a95d47ea5d9ee31e25c (patch)
tree9959dd4157c222794bcef6b6b320bae616aea7c1
parent40e77740270ee3bc9d7241aa3fe9d4c6f1695859 (diff)
downloadhaskell-0279a7d327a3b962ffa93a95d47ea5d9ee31e25c.tar.gz
Typechecker support for explicitly-bidirectional pattern synonyms
-rw-r--r--compiler/typecheck/TcPatSyn.lhs39
1 files changed, 23 insertions, 16 deletions
diff --git a/compiler/typecheck/TcPatSyn.lhs b/compiler/typecheck/TcPatSyn.lhs
index 82fa999f34..d72acbadfb 100644
--- a/compiler/typecheck/TcPatSyn.lhs
+++ b/compiler/typecheck/TcPatSyn.lhs
@@ -205,16 +205,27 @@ tcPatSynWrapper lname lpat dir args univ_tvs ex_tvs theta pat_ty
(ImplicitBidirectional, Nothing) ->
cannotInvertPatSynErr lpat
(ImplicitBidirectional, Just lexpr) ->
- fmap Just $ tc_pat_syn_wrapper_from_expr lname lexpr args univ_tvs ex_tvs theta pat_ty }
-
-tc_pat_syn_wrapper_from_expr :: Located Name
- -> LHsExpr Name
- -> [Var]
- -> [TyVar] -> [TyVar]
- -> ThetaType
- -> Type
- -> TcM (Id, LHsBinds Id)
-tc_pat_syn_wrapper_from_expr (L loc name) lexpr args univ_tvs ex_tvs theta pat_ty
+ fmap Just $ mkWrapper $ \wrapper_lname args' ->
+ do { let wrapper_args = map (noLoc . VarPat . Var.varName) args'
+ wrapper_match = mkMatch wrapper_args lexpr EmptyLocalBinds
+ bind = mkTopFunBind Generated wrapper_lname [wrapper_match]
+ ; return bind }
+ (ExplicitBidirectional mg, _) ->
+ fmap Just $ mkWrapper $ \wrapper_lname _args' ->
+ return FunBind{ fun_id = wrapper_lname
+ , fun_infix = False
+ , fun_matches = mg
+ , fun_co_fn = idHsWrapper
+ , bind_fvs = placeHolderNames
+ , fun_tick = Nothing } }
+ where
+ mkWrapper = mkPatSynWrapper lname args univ_tvs ex_tvs theta pat_ty
+
+mkPatSynWrapper :: Located Name
+ -> [Var] -> [TyVar] -> [TyVar] -> ThetaType -> Type
+ -> (Located Name -> [Var] -> TcM (HsBind Name))
+ -> TcM (Id, LHsBinds Id)
+mkPatSynWrapper (L loc name) args univ_tvs ex_tvs theta pat_ty mk_bind
= do { let qtvs = univ_tvs ++ ex_tvs
; (subst, wrapper_tvs) <- tcInstSkolTyVars qtvs
; let wrapper_theta = substTheta subst theta
@@ -227,21 +238,17 @@ tc_pat_syn_wrapper_from_expr (L loc name) lexpr args univ_tvs ex_tvs theta pat_t
; let wrapper_lname = L loc wrapper_name
wrapper_id = mkExportedLocalId VanillaId wrapper_name wrapper_sigma
- ; let wrapper_args = map (noLoc . VarPat . Var.varName) args'
- wrapper_match = mkMatch wrapper_args lexpr EmptyLocalBinds
- bind = mkTopFunBind Generated wrapper_lname [wrapper_match]
- lbind = noLoc bind
+ ; bind <- mk_bind wrapper_lname args'
; let sig = TcSigInfo{ sig_id = wrapper_id
, sig_tvs = map (\tv -> (Nothing, tv)) wrapper_tvs
, sig_theta = wrapper_theta
, sig_tau = wrapper_tau
, sig_loc = loc
}
- ; (wrapper_binds, _, _) <- tcPolyCheck NonRecursive (const []) sig lbind
+ ; (wrapper_binds, _, _) <- tcPolyCheck NonRecursive (const []) sig (noLoc bind)
; traceTc "tcPatSynDecl wrapper" $ ppr wrapper_binds
; traceTc "tcPatSynDecl wrapper type" $ ppr (varType wrapper_id)
; return (wrapper_id, wrapper_binds) }
-
\end{code}
Note [As-patterns in pattern synonym definitions]