[commit: ghc] master: Add comments to describe AbsBinds (72f8eab)
Simon Peyton Jones
simonpj at microsoft.com
Mon Apr 22 13:59:39 CEST 2013
Repository : http://darcs.haskell.org/ghc.git/
On branch : master
https://github.com/ghc/ghc/commit/72f8eab97d919d39416135de5757e31f15defa67
>---------------------------------------------------------------
commit 72f8eab97d919d39416135de5757e31f15defa67
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Sat Apr 6 00:05:40 2013 +0100
Add comments to describe AbsBinds
>---------------------------------------------------------------
compiler/hsSyn/HsBinds.lhs | 64 +++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 61 insertions(+), 3 deletions(-)
diff --git a/compiler/hsSyn/HsBinds.lhs b/compiler/hsSyn/HsBinds.lhs
index 8d5fa9a..ab936db 100644
--- a/compiler/hsSyn/HsBinds.lhs
+++ b/compiler/hsSyn/HsBinds.lhs
@@ -163,9 +163,7 @@ data HsBindLR idL idR
-- 2. ftvs is a subset of tvs
-- 3. ftvs includes all tyvars free in ds
--
- -- See section 9 of static semantics paper for more details.
- -- (You can get a PhD for explaining the True Meaning
- -- of this last construct.)
+ -- See Note [AbsBinds]
data ABExport id
= ABE { abe_poly :: id -- Any INLINE pragmas is attached to this Id
@@ -180,6 +178,66 @@ placeHolderNames :: NameSet
placeHolderNames = panic "placeHolderNames"
\end{code}
+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
+ 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* deugaring we will get something
+like this
+
+ M.reverse :: forall a. [a] -> [a]
+ = /\a. letrec
+ reverse :: [a] -> [a] = \xs -> case xs of
+ [] -> []
+ (x:xs) -> reverse xs ++ [x]
+ in reverse
+
+Notice that 'M.reverse' is polymorphic as expected, but there is a local
+defintion for plain 'reverse' which is *monomorphic*. The type variable
+'a' scopes over the entire letrec.
+
+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_exports = [ABE { abe_poly = M.reverse :: forall a. [a] -> [a],
+ , abe_mono = reverse :: a -> a}]
+ , 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_binds is the *monomorphic* bindings of the group
+ * 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
+abs_exports. The bindings in abs_binds are for fresh, local, Ids with
+a *monomorphic* Id.
+
+If there is a group of mutually recusive functions without type
+signatures, we get one AbsBinds with the monomorphic versions of the
+bindings in abs_binds, and one element of abe_exports for each
+variable bound in the mutually recursive group. This is true even for
+pattern bindings. Example:
+ (f,g) = (\x -> x, f)
+After type checking we get
+ AbsBinds { abs_tvs = [a]
+ , abs_exports = [ ABE { abe_poly = M.f :: forall a. a -> a
+ , abe_mono = f :: a -> a }
+ , ABE { abe_poly = M.g :: forall a. a -> a
+ , abe_mono = g :: a -> a }]
+ , abs_binds = { (f,g) = (\x -> x, f) }
+
Note [AbsBinds wrappers]
~~~~~~~~~~~~~~~~~~~~~~~~
Consdider
More information about the ghc-commits
mailing list