[commit: ghc] master: Improve comments on AbsBinds (5c93df9)
git at git.haskell.org
git at git.haskell.org
Mon Jun 19 21:43:38 UTC 2017
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/5c93df90a96494229b60bbed0971a4b08c0326a6/ghc
>---------------------------------------------------------------
commit 5c93df90a96494229b60bbed0971a4b08c0326a6
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Mon Jun 19 11:50:37 2017 +0100
Improve comments on AbsBinds
See Trac #13827.
>---------------------------------------------------------------
5c93df90a96494229b60bbed0971a4b08c0326a6
compiler/hsSyn/HsBinds.hs | 91 ++++++++++++++++++++++++++++-------------------
1 file changed, 55 insertions(+), 36 deletions(-)
diff --git a/compiler/hsSyn/HsBinds.hs b/compiler/hsSyn/HsBinds.hs
index b760cb3..d0c345a 100644
--- a/compiler/hsSyn/HsBinds.hs
+++ b/compiler/hsSyn/HsBinds.hs
@@ -301,15 +301,57 @@ deriving instance (DataId idL, DataId idR) => Data (PatSynBind idL idR)
{-
Note [AbsBinds]
~~~~~~~~~~~~~~~
-The AbsBinds constructor is used in the output of the type checker, to record
-*typechecked* and *generalised* bindings. Consider a module M, with this
-top-level binding, where there is no type signature for M.reverse,
+The AbsBinds constructor is used in the output of the type checker, to
+record *typechecked* and *generalised* bindings. Specifically
+
+ AbsBinds { abs_tvs = tvs
+ , abs_ev_vars = [d1,d2]
+ , abs_exports = [ABE { abe_poly = fp, abe_mono = fm
+ , abe_wrap = fwrap }
+ ABE { slly for g } ]
+ , abs_ev_binds = DBINDS
+ , abs_binds = BIND[fm,gm] }
+
+where 'BIND' binds the monomorphic Ids 'fm' and 'gm', means
+
+ fp = fwrap [/\ tvs. \d1 d2. letrec { DBINDS ]
+ [ ; BIND[fm,gm] } ]
+ [ in fm ]
+
+ gp = ...same again, with gm instead of fm
+
+The 'fwrap' is an impedence-matcher that typically does nothing; see
+Note [ABExport wrapper].
+
+This is a pretty bad translation, because it duplicates all the bindings.
+So the desugarer tries to do a better job:
+
+ fp = /\ [a,b] -> \ [d1,d2] -> case tp [a,b] [d1,d2] of
+ (fm,gm) -> fm
+ ..ditto for gp..
+
+ tp = /\ [a,b] -> \ [d1,d2] -> letrec { DBINDS; BIND }
+ in (fm,gm)
+
+In general:
+
+ * abs_tvs are the type variables over which the binding group is
+ generalised
+ * abs_ev_var are the evidence variables (usually dictionaries)
+ over which the binding group is generalised
+ * abs_binds are the monomorphic bindings
+ * abs_ex_binds are the evidence bindings that wrap the abs_binds
+ * abs_exports connects the monomorphic Ids bound by abs_binds
+ with the polymorphic Ids bound by the AbsBinds itself.
+
+For example, consider a module M, with this top-level binding, where
+there is no type signature for M.reverse,
M.reverse [] = []
M.reverse (x:xs) = M.reverse xs ++ [x]
-In Hindley-Milner, a recursive binding is typechecked with the *recursive* uses
-being *monomorphic*. So after typechecking *and* desugaring we will get something
-like this
+In Hindley-Milner, a recursive binding is typechecked with the
+*recursive* uses being *monomorphic*. So after typechecking *and*
+desugaring we will get something like this
M.reverse :: forall a. [a] -> [a]
= /\a. letrec
@@ -326,19 +368,22 @@ That's after desugaring. What about after type checking but before
desugaring? That's where AbsBinds comes in. It looks like this:
AbsBinds { abs_tvs = [a]
+ , abs_ev_vars = []
, abs_exports = [ABE { abe_poly = M.reverse :: forall a. [a] -> [a],
, abe_mono = reverse :: [a] -> [a]}]
+ , abs_ev_binds = {}
, abs_binds = { reverse :: [a] -> [a]
= \xs -> case xs of
[] -> []
(x:xs) -> reverse xs ++ [x] } }
Here,
- * abs_tvs says what type variables are abstracted over the binding group,
- just 'a' in this case.
+
+ * abs_tvs says what type variables are abstracted over the binding
+ group, just 'a' in this case.
* abs_binds is the *monomorphic* bindings of the group
- * abs_exports describes how to get the polymorphic Id 'M.reverse' from the
- monomorphic one 'reverse'
+ * abs_exports describes how to get the polymorphic Id 'M.reverse'
+ from the monomorphic one 'reverse'
Notice that the *original* function (the polymorphic one you thought
you were defining) appears in the abe_poly field of the
@@ -537,32 +582,6 @@ plusHsValBinds (ValBindsOut ds1 sigs1) (ValBindsOut ds2 sigs2)
plusHsValBinds _ _
= panic "HsBinds.plusHsValBinds"
-{-
-What AbsBinds means
-~~~~~~~~~~~~~~~~~~~
- AbsBinds tvs
- [d1,d2]
- [(tvs1, f1p, f1m),
- (tvs2, f2p, f2m)]
- BIND
-means
-
- f1p = /\ tvs -> \ [d1,d2] -> letrec DBINDS and BIND
- in fm
-
- gp = ...same again, with gm instead of fm
-
-This is a pretty bad translation, because it duplicates all the bindings.
-So the desugarer tries to do a better job:
-
- fp = /\ [a,b] -> \ [d1,d2] -> case tp [a,b] [d1,d2] of
- (fm,gm) -> fm
- ..ditto for gp..
-
- tp = /\ [a,b] -> \ [d1,d2] -> letrec DBINDS and BIND
- in (fm,gm)
--}
-
instance (SourceTextX idL, SourceTextX idR,
OutputableBndrId idL, OutputableBndrId idR)
=> Outputable (HsBindLR idL idR) where
More information about the ghc-commits
mailing list