summaryrefslogtreecommitdiff
path: root/compiler/prelude/TysPrim.hs
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2016-06-15 13:27:12 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2016-06-15 17:36:02 +0100
commite368f3265b80aeb337fbac3f6a70ee54ab14edfd (patch)
treec38b396e267a5f8172751daa8f985c22d6f92760 /compiler/prelude/TysPrim.hs
parent77bb09270c70455bbd547470c4e995707d19f37d (diff)
downloadhaskell-e368f3265b80aeb337fbac3f6a70ee54ab14edfd.tar.gz
Major patch to introduce TyConBinder
Before this patch, following the TypeInType innovations, each TyCon had two lists: - tyConBinders :: [TyBinder] - tyConTyVars :: [TyVar] They were in 1-1 correspondence and contained overlapping information. More broadly, there were many places where we had to pass around this pair of lists, instead of a single list. This commit tidies all that up, by having just one list of binders in a TyCon: - tyConBinders :: [TyConBinder] The new data types look like this: Var.hs: data TyVarBndr tyvar vis = TvBndr tyvar vis data VisibilityFlag = Visible | Specified | Invisible type TyVarBinder = TyVarBndr TyVar VisibilityFlag TyCon.hs: type TyConBinder = TyVarBndr TyVar TyConBndrVis data TyConBndrVis = NamedTCB VisibilityFlag | AnonTCB TyCoRep.hs: data TyBinder = Named TyVarBinder | Anon Type Note that Var.TyVarBdr has moved from TyCoRep and has been made polymorphic in the tyvar and visiblity fields: type TyVarBinder = TyVarBndr TyVar VisibilityFlag -- Used in ForAllTy type TyConBinder = TyVarBndr TyVar TyConBndrVis -- Used in TyCon type IfaceForAllBndr = TyVarBndr IfaceTvBndr VisibilityFlag type IfaceTyConBinder = TyVarBndr IfaceTvBndr TyConBndrVis -- Ditto, in interface files There are a zillion knock-on changes, but everything arises from these types. It was a bit fiddly to get the module loops to work out right! Some smaller points ~~~~~~~~~~~~~~~~~~~ * Nice new functions TysPrim.mkTemplateKiTyVars TysPrim.mkTemplateTyConBinders which help you make the tyvar binders for dependently-typed TyCons. See comments with their definition. * The change showed up a bug in TcGenGenerics.tc_mkRepTy, where the code was making an assumption about the order of the kind variables in the kind of GHC.Generics.(:.:). I fixed this; see TcGenGenerics.mkComp.
Diffstat (limited to 'compiler/prelude/TysPrim.hs')
-rw-r--r--compiler/prelude/TysPrim.hs162
1 files changed, 104 insertions, 58 deletions
diff --git a/compiler/prelude/TysPrim.hs b/compiler/prelude/TysPrim.hs
index e0be093420..376a0bbe43 100644
--- a/compiler/prelude/TysPrim.hs
+++ b/compiler/prelude/TysPrim.hs
@@ -12,12 +12,16 @@
module TysPrim(
mkPrimTyConName, -- For implicit parameters in TysWiredIn only
- mkTemplateTyVars,
+ mkTemplateKindVars, mkTemplateTyVars, mkTemplateTyVarsFrom,
+ mkTemplateKiTyVars,
+
+ mkTemplateTyConBinders, mkTemplateKindTyConBinders,
+ mkTemplateAnonTyConBinders,
+
alphaTyVars, alphaTyVar, betaTyVar, gammaTyVar, deltaTyVar,
alphaTys, alphaTy, betaTy, gammaTy, deltaTy,
runtimeRep1TyVar, runtimeRep2TyVar, runtimeRep1Ty, runtimeRep2Ty,
openAlphaTy, openBetaTy, openAlphaTyVar, openBetaTyVar,
- kKiVar,
-- Kind constructors...
tYPETyConName, unliftedTypeKindTyConName,
@@ -88,7 +92,7 @@ import {-# SOURCE #-} TysWiredIn
, word32ElemRepDataConTy, word64ElemRepDataConTy, floatElemRepDataConTy
, doubleElemRepDataConTy )
-import Var ( TyVar, KindVar, mkTyVar )
+import Var ( TyVar, mkTyVar )
import Name
import TyCon
import SrcLoc
@@ -96,8 +100,8 @@ import Unique
import PrelNames
import FastString
import Outputable
-import TyCoRep -- doesn't need special access, but this is easier to avoid
- -- import loops
+import TyCoRep -- Doesn't need special access, but this is easier to avoid
+ -- import loops which show up if you import Type instead
import Data.Char
@@ -212,16 +216,76 @@ alphaTyVars is a list of type variables for use in templates:
["a", "b", ..., "z", "t1", "t2", ... ]
-}
+mkTemplateKindVars :: [Kind] -> [TyVar]
+-- k0 with unique (mkAlphaTyVarUnique 0)
+-- k1 with unique (mkAlphaTyVarUnique 1)
+-- ... etc
+mkTemplateKindVars kinds
+ = [ mkTyVar name kind
+ | (kind, u) <- kinds `zip` [0..]
+ , let occ = mkTyVarOccFS (mkFastString ('k' : show u))
+ name = mkInternalName (mkAlphaTyVarUnique u) occ noSrcSpan
+ ]
+
+mkTemplateTyVarsFrom :: Int -> [Kind] -> [TyVar]
+-- a with unique (mkAlphaTyVarUnique n)
+-- b with unique (mkAlphaTyVarUnique n+1)
+-- ... etc
+-- Typically called as
+-- mkTemplateTyVarsFrom (legth kv_bndrs) kinds
+-- where kv_bndrs are the kind-level binders of a TyCon
+mkTemplateTyVarsFrom n kinds
+ = [ mkTyVar name kind
+ | (kind, index) <- zip kinds [0..],
+ let ch_ord = index + ord 'a'
+ name_str | ch_ord <= ord 'z' = [chr ch_ord]
+ | otherwise = 't':show index
+ uniq = mkAlphaTyVarUnique (index + n)
+ name = mkInternalName uniq occ noSrcSpan
+ occ = mkTyVarOccFS (mkFastString name_str)
+ ]
+
mkTemplateTyVars :: [Kind] -> [TyVar]
-mkTemplateTyVars kinds =
- [ mkTyVar (mkInternalName (mkAlphaTyVarUnique u)
- (mkTyVarOccFS (mkFastString name))
- noSrcSpan) k
- | (k,u) <- zip kinds [2..],
- let name | c <= 'z' = [c]
- | otherwise = 't':show u
- where c = chr (u-2 + ord 'a')
- ]
+mkTemplateTyVars = mkTemplateTyVarsFrom 1
+
+mkTemplateTyConBinders
+ :: [Kind] -- [k1, .., kn] Kinds of kind-forall'd vars
+ -> ([Kind] -> [Kind]) -- Arg is [kv1:k1, ..., kvn:kn]
+ -- same length as first arg
+ -- Result is anon arg kinds
+ -> [TyConBinder]
+mkTemplateTyConBinders kind_var_kinds mk_anon_arg_kinds
+ = kv_bndrs ++ tv_bndrs
+ where
+ kv_bndrs = mkTemplateKindTyConBinders kind_var_kinds
+ anon_kinds = mk_anon_arg_kinds (mkTyVarTys (binderVars kv_bndrs))
+ tv_bndrs = mkTemplateAnonTyConBindersFrom (length kv_bndrs) anon_kinds
+
+mkTemplateKiTyVars
+ :: [Kind] -- [k1, .., kn] Kinds of kind-forall'd vars
+ -> ([Kind] -> [Kind]) -- Arg is [kv1:k1, ..., kvn:kn]
+ -- same length as first arg
+ -- Result is anon arg kinds [ak1, .., akm]
+ -> [TyVar] -- [kv1:k1, ..., kvn:kn, av1:ak1, ..., avm:akm]
+-- Example: if you want the tyvars for
+-- forall (r:RuntimeRep) (a:TYPE r) (b:*). blah
+-- call mkTemplateKiTyVars [RuntimeRep] (\[r]. [TYPE r, *)
+mkTemplateKiTyVars kind_var_kinds mk_arg_kinds
+ = kv_bndrs ++ tv_bndrs
+ where
+ kv_bndrs = mkTemplateKindVars kind_var_kinds
+ anon_kinds = mk_arg_kinds (mkTyVarTys kv_bndrs)
+ tv_bndrs = mkTemplateTyVarsFrom (length kv_bndrs) anon_kinds
+
+mkTemplateKindTyConBinders :: [Kind] -> [TyConBinder]
+-- Makes named, Specified binders
+mkTemplateKindTyConBinders kinds = [mkNamedTyConBinder Specified tv | tv <- mkTemplateKindVars kinds]
+
+mkTemplateAnonTyConBinders :: [Kind] -> [TyConBinder]
+mkTemplateAnonTyConBinders kinds = map mkAnonTyConBinder (mkTemplateTyVars kinds)
+
+mkTemplateAnonTyConBindersFrom :: Int -> [Kind] -> [TyConBinder]
+mkTemplateAnonTyConBindersFrom n kinds = map mkAnonTyConBinder (mkTemplateTyVarsFrom n kinds)
alphaTyVars :: [TyVar]
alphaTyVars = mkTemplateTyVars $ repeat liftedTypeKind
@@ -250,10 +314,6 @@ openAlphaTy, openBetaTy :: Type
openAlphaTy = mkTyVarTy openAlphaTyVar
openBetaTy = mkTyVarTy openBetaTyVar
-kKiVar :: KindVar
-kKiVar = (mkTemplateTyVars $ repeat liftedTypeKind) !! 10
- -- the 10 selects the 11th letter in the alphabet: 'k'
-
{-
************************************************************************
* *
@@ -266,9 +326,10 @@ funTyConName :: Name
funTyConName = mkPrimTyConName (fsLit "(->)") funTyConKey funTyCon
funTyCon :: TyCon
-funTyCon = mkFunTyCon funTyConName (map Anon [liftedTypeKind, liftedTypeKind])
- tc_rep_nm
+funTyCon = mkFunTyCon funTyConName tc_bndrs tc_rep_nm
where
+ tc_bndrs = mkTemplateAnonTyConBinders [liftedTypeKind, liftedTypeKind]
+
-- You might think that (->) should have type (?? -> ? -> *), and you'd be right
-- But if we do that we get kind errors when saying
-- instance Control.Arrow (->)
@@ -331,7 +392,7 @@ tYPETyCon, unliftedTypeKindTyCon :: TyCon
tYPETyConName, unliftedTypeKindTyConName :: Name
tYPETyCon = mkKindTyCon tYPETyConName
- [Anon runtimeRepTy]
+ (mkTemplateAnonTyConBinders [runtimeRepTy])
liftedTypeKind
[Nominal]
(mkPrelTyConRepName tYPETyConName)
@@ -340,8 +401,7 @@ tYPETyCon = mkKindTyCon tYPETyConName
-- NB: unlifted is wired in because there is no way to parse it in
-- Haskell. That's the only reason for wiring it in.
unliftedTypeKindTyCon = mkSynonymTyCon unliftedTypeKindTyConName
- [] liftedTypeKind
- [] []
+ [] liftedTypeKind []
(tYPE (TyConApp ptrRepUnliftedDataConTyCon []))
--------------------------
@@ -379,7 +439,7 @@ pcPrimTyCon :: Name -> [Role] -> PrimRep -> TyCon
pcPrimTyCon name roles rep
= mkPrimTyCon name binders result_kind roles
where
- binders = map (const (Anon liftedTypeKind)) roles
+ binders = mkTemplateAnonTyConBinders (map (const liftedTypeKind) roles)
result_kind = tYPE rr
rr = case rep of
@@ -682,11 +742,10 @@ mkProxyPrimTy k ty = TyConApp proxyPrimTyCon [k, ty]
proxyPrimTyCon :: TyCon
proxyPrimTyCon = mkPrimTyCon proxyPrimTyConName binders res_kind [Nominal,Nominal]
- where binders = [ Named (TvBndr kv Specified)
- , Anon k ]
- res_kind = tYPE voidRepDataConTy
- kv = kKiVar
- k = mkTyVarTy kv
+ where
+ -- Kind: forall k. k -> Void#
+ binders = mkTemplateTyConBinders [liftedTypeKind] (\ks-> ks)
+ res_kind = tYPE voidRepDataConTy
{- *********************************************************************
@@ -699,46 +758,33 @@ proxyPrimTyCon = mkPrimTyCon proxyPrimTyConName binders res_kind [Nominal,Nomina
eqPrimTyCon :: TyCon -- The representation type for equality predicates
-- See Note [The equality types story]
eqPrimTyCon = mkPrimTyCon eqPrimTyConName binders res_kind roles
- where binders = [ Named (TvBndr kv1 Specified)
- , Named (TvBndr kv2 Specified)
- , Anon k1
- , Anon k2 ]
- res_kind = tYPE voidRepDataConTy
- [kv1, kv2] = mkTemplateTyVars [liftedTypeKind, liftedTypeKind]
- k1 = mkTyVarTy kv1
- k2 = mkTyVarTy kv2
- roles = [Nominal, Nominal, Nominal, Nominal]
+ where
+ -- Kind :: forall k1 k2. k1 -> k2 -> Void#
+ binders = mkTemplateTyConBinders [liftedTypeKind, liftedTypeKind] (\ks -> ks)
+ res_kind = tYPE voidRepDataConTy
+ roles = [Nominal, Nominal, Nominal, Nominal]
-- like eqPrimTyCon, but the type for *Representational* coercions
-- this should only ever appear as the type of a covar. Its role is
-- interpreted in coercionRole
eqReprPrimTyCon :: TyCon -- See Note [The equality types story]
eqReprPrimTyCon = mkPrimTyCon eqReprPrimTyConName binders res_kind roles
- where binders = [ Named (TvBndr kv1 Specified)
- , Named (TvBndr kv2 Specified)
- , Anon k1
- , Anon k2 ]
- res_kind = tYPE voidRepDataConTy
- [kv1, kv2] = mkTemplateTyVars [liftedTypeKind, liftedTypeKind]
- k1 = mkTyVarTy kv1
- k2 = mkTyVarTy kv2
- roles = [Nominal, Nominal, Representational, Representational]
+ where
+ -- Kind :: forall k1 k2. k1 -> k2 -> Void#
+ binders = mkTemplateTyConBinders [liftedTypeKind, liftedTypeKind] (\ks -> ks)
+ res_kind = tYPE voidRepDataConTy
+ roles = [Nominal, Nominal, Representational, Representational]
-- like eqPrimTyCon, but the type for *Phantom* coercions.
-- This is only used to make higher-order equalities. Nothing
-- should ever actually have this type!
eqPhantPrimTyCon :: TyCon
-eqPhantPrimTyCon = mkPrimTyCon eqPhantPrimTyConName binders res_kind
- [Nominal, Nominal, Phantom, Phantom]
- where binders = [ Named (TvBndr kv1 Specified)
- , Named (TvBndr kv2 Specified)
- , Anon k1
- , Anon k2 ]
- res_kind = tYPE voidRepDataConTy
- [kv1, kv2] = mkTemplateTyVars [liftedTypeKind, liftedTypeKind]
- k1 = mkTyVarTy kv1
- k2 = mkTyVarTy kv2
-
+eqPhantPrimTyCon = mkPrimTyCon eqPhantPrimTyConName binders res_kind roles
+ where
+ -- Kind :: forall k1 k2. k1 -> k2 -> Void#
+ binders = mkTemplateTyConBinders [liftedTypeKind, liftedTypeKind] (\ks -> ks)
+ res_kind = tYPE voidRepDataConTy
+ roles = [Nominal, Nominal, Phantom, Phantom]
{- *********************************************************************
* *