----------------------------------
Implement kinded type declarations
----------------------------------
This commit allows the programmer to supply kinds in
* data decls
* type decls
* class decls
* 'forall's in types
e.g. data T (x :: *->*) = MkT
type Composer c = forall (x :: * -> *) (y :: * -> *) (z :: * -> *).
(c y z) -> (c x y) -> (c x z);
This is occasionally useful.
It turned out to be convenient to add the form
(type :: kind)
to the syntax of types too, so you can put kind signatures in types as well.
import OccName ( NameSpace, tvName )
import Var ( TyVar, tyVarKind )
import Subst ( substTyWith )
import OccName ( NameSpace, tvName )
import Var ( TyVar, tyVarKind )
import Subst ( substTyWith )
-import PprType ( {- instance Outputable Kind -}, pprParendKind )
+import PprType ( {- instance Outputable Kind -}, pprParendKind, pprKind )
import BasicTypes ( Boxity(..), Arity, IPName, tupleParens )
import PrelNames ( mkTupConRdrName, listTyConKey, parrTyConKey,
usOnceTyConKey, usManyTyConKey, hasKey,
import BasicTypes ( Boxity(..), Arity, IPName, tupleParens )
import PrelNames ( mkTupConRdrName, listTyConKey, parrTyConKey,
usOnceTyConKey, usManyTyConKey, hasKey,
-- these next two are only used in interfaces
| HsPredTy (HsPred name)
-- these next two are only used in interfaces
| HsPredTy (HsPred name)
+ | HsKindSig (HsType name) -- (ty :: kind)
+ Kind -- A type with a kind signature
+
-----------------------
hsUsOnce, hsUsMany :: HsType RdrName
-----------------------
hsUsOnce, hsUsMany :: HsType RdrName
(sep [p1, (<>) (ptext SLIT("-> ")) p2])
ppr_mono_ty ctxt_prec (HsTupleTy con tys) = hsTupParens con (interpp'SP tys)
(sep [p1, (<>) (ptext SLIT("-> ")) p2])
ppr_mono_ty ctxt_prec (HsTupleTy con tys) = hsTupParens con (interpp'SP tys)
+ppr_mono_ty ctxt_prec (HsKindSig ty kind) = parens (ppr_mono_ty pREC_TOP ty <+> dcolon <+> pprKind kind)
ppr_mono_ty ctxt_prec (HsListTy ty) = brackets (ppr_mono_ty pREC_TOP ty)
ppr_mono_ty ctxt_prec (HsPArrTy ty) = pabrackets (ppr_mono_ty pREC_TOP ty)
where
ppr_mono_ty ctxt_prec (HsListTy ty) = brackets (ppr_mono_ty pREC_TOP ty)
ppr_mono_ty ctxt_prec (HsPArrTy ty) = pabrackets (ppr_mono_ty pREC_TOP ty)
where
eq_hsType env (HsListTy ty1) (HsListTy ty2)
= eq_hsType env ty1 ty2
eq_hsType env (HsListTy ty1) (HsListTy ty2)
= eq_hsType env ty1 ty2
+eq_hsType env (HsKindSig ty1 k1) (HsKindSig ty2 k2)
+ = eq_hsType env ty1 ty2 && k1 `eqKind` k2
+
eq_hsType env (HsPArrTy ty1) (HsPArrTy ty2)
= eq_hsType env ty1 ty2
eq_hsType env (HsPArrTy ty1) (HsPArrTy ty2)
= eq_hsType env ty1 ty2
| ITdarrow
| ITminus
| ITbang
| ITdarrow
| ITminus
| ITbang
| ITdot
| ITbiglam -- GHC-extension symbols
| ITdot
| ITbiglam -- GHC-extension symbols
,("=>", ITdarrow)
,("-", ITminus)
,("!", ITbang)
,("=>", ITdarrow)
,("-", ITminus)
,("!", ITbang)
,(".", ITdot) -- sadly, for 'forall a . t'
]
\end{code}
,(".", ITdot) -- sadly, for 'forall a . t'
]
\end{code}
ty -> checkDictTy ty [] `thenP` \ dict_ty->
returnP (HsForAllTy Nothing [] dict_ty)
ty -> checkDictTy ty [] `thenP` \ dict_ty->
returnP (HsForAllTy Nothing [] dict_ty)
-checkTyVars :: [RdrNameHsTyVar] -> P [RdrNameHsType]
+checkTyVars :: [RdrNameHsType] -> P [RdrNameHsTyVar]
checkTyVars tvs = mapP chk tvs
where
checkTyVars tvs = mapP chk tvs
where
- chk (UserTyVar tv) = returnP (HsTyVar tv)
- chk other = parseError "Illegal kinded type variable"
+ chk (HsKindSig (HsTyVar tv) k) = returnP (IfaceTyVar tv k)
+ chk (HsTyVar tv) = returnP (UserTyVar tv)
+ chk other = parseError "Type found where type variable expected"
checkContext :: RdrNameHsType -> P RdrNameContext
checkContext (HsTupleTy _ ts) -- (Eq a, Ord b) shows up as a tuple type
checkContext :: RdrNameHsType -> P RdrNameContext
checkContext (HsTupleTy _ ts) -- (Eq a, Ord b) shows up as a tuple type
returnP [p]
checkPred :: RdrNameHsType -> P (HsPred RdrName)
returnP [p]
checkPred :: RdrNameHsType -> P (HsPred RdrName)
+-- Watch out.. in ...deriving( Show )... we use checkPred on
+-- the list of partially applied predicates in the deriving,
+-- so there can be zero args.
checkPred (HsPredTy (HsIParam n ty)) = returnP (HsIParam n ty)
checkPred (HsPredTy (HsIParam n ty)) = returnP (HsIParam n ty)
-checkPred (HsAppTy l r)
- = go l [r]
+checkPred ty
+ = go ty []
where
go (HsTyVar t) args | not (isRdrTyVar t)
= returnP (HsClassP t args)
where
go (HsTyVar t) args | not (isRdrTyVar t)
= returnP (HsClassP t args)
{- -*-haskell-*-
-----------------------------------------------------------------------------
{- -*-haskell-*-
-----------------------------------------------------------------------------
-$Id: Parser.y,v 1.85 2002/02/11 09:27:22 simonpj Exp $
+$Id: Parser.y,v 1.86 2002/02/11 15:16:26 simonpj Exp $
import SrcLoc ( SrcLoc )
import Module
import CmdLineOpts ( opt_SccProfilingOn )
import SrcLoc ( SrcLoc )
import Module
import CmdLineOpts ( opt_SccProfilingOn )
+import Type ( Kind, mkArrowKind, liftedTypeKind )
import BasicTypes ( Boxity(..), Fixity(..), FixityDirection(..), IPName(..),
NewOrData(..), StrictnessMark(..), Activation(..) )
import Panic
import BasicTypes ( Boxity(..), Fixity(..), FixityDirection(..), IPName(..),
NewOrData(..), StrictnessMark(..), Activation(..) )
import Panic
-----------------------------------------------------------------------------
Conflicts: 21 shift/reduce, -=chak[4Feb2]
-----------------------------------------------------------------------------
Conflicts: 21 shift/reduce, -=chak[4Feb2]
-8 for abiguity in 'if x then y else z + 1'
+9 for abiguity in 'if x then y else z + 1'
(shift parses as 'if x then y else (z + 1)', as per longest-parse rule)
(shift parses as 'if x then y else (z + 1)', as per longest-parse rule)
+ 8 because op might be: - ! * . `x` VARSYM CONSYM QVARSYM QCONSYM
1 for ambiguity in 'if x then y else z :: T'
(shift parses as 'if x then y else (z :: T)', as per longest-parse rule)
1 for ambiguity in 'if x then y else z :: T'
(shift parses as 'if x then y else (z :: T)', as per longest-parse rule)
+1 for ambiguity in 'if x then y else z with ?x=3'
+ (shift parses as 'if x then y else (z with ?x=3)'
+
3 for ambiguity in 'case x of y :: a -> b'
(don't know whether to reduce 'a' as a btype or shift the '->'.
conclusion: bogus expression anyway, doesn't matter)
3 for ambiguity in 'case x of y :: a -> b'
(don't know whether to reduce 'a' as a btype or shift the '->'.
conclusion: bogus expression anyway, doesn't matter)
'=>' { ITdarrow }
'-' { ITminus }
'!' { ITbang }
'=>' { ITdarrow }
'-' { ITminus }
'!' { ITbang }
'.' { ITdot }
'{' { ITocurly } -- special symbols
'.' { ITdot }
'{' { ITocurly } -- special symbols
| topdecl { [$1] }
topdecl :: { RdrBinding }
| topdecl { [$1] }
topdecl :: { RdrBinding }
- : srcloc 'type' simpletype '=' ctype
+ : srcloc 'type' tycon tv_bndrs '=' ctype
-- Note ctype, not sigtype.
-- We allow an explicit for-all but we don't insert one
-- in type Foo a = (b,b)
-- Instead we just say b is out of scope
-- Note ctype, not sigtype.
-- We allow an explicit for-all but we don't insert one
-- in type Foo a = (b,b)
-- Instead we just say b is out of scope
- { RdrHsDecl (TyClD (TySynonym (fst $3) (snd $3) $5 $1)) }
+ { RdrHsDecl (TyClD (TySynonym $3 $4 $6 $1)) }
+
| srcloc 'data' tycl_hdr constrs deriving
{% returnP (RdrHsDecl (TyClD
| srcloc 'data' tycl_hdr constrs deriving
{% returnP (RdrHsDecl (TyClD
(groupBindings $4)
in RdrHsDecl (InstD (InstDecl $3 binds sigs Nothing $1)) }
(groupBindings $4)
in RdrHsDecl (InstD (InstDecl $3 binds sigs Nothing $1)) }
- | srcloc 'default' '(' types0 ')' { RdrHsDecl (DefD (DefaultDecl $4 $1)) }
+ | srcloc 'default' '(' comma_types0 ')' { RdrHsDecl (DefD (DefaultDecl $4 $1)) }
| 'foreign' fdecl { RdrHsDecl $2 }
| '{-# DEPRECATED' deprecations '#-}' { $2 }
| '{-# RULES' rules '#-}' { $2 }
| 'foreign' fdecl { RdrHsDecl $2 }
| '{-# DEPRECATED' deprecations '#-}' { $2 }
| '{-# RULES' rules '#-}' { $2 }
-- (Eq a, Ord b) => T a b
-- Rather a lot of inlining here, else we get reduce/reduce errors
tycl_hdr :: { (RdrNameContext, RdrName, [RdrNameHsTyVar]) }
-- (Eq a, Ord b) => T a b
-- Rather a lot of inlining here, else we get reduce/reduce errors
tycl_hdr :: { (RdrNameContext, RdrName, [RdrNameHsTyVar]) }
- : '(' types ')' '=>' tycon tyvars {% mapP checkPred $2 `thenP` \ cxt ->
- returnP (cxt, $5, $6) }
- | tycon tyvars '=>' tycon tyvars {% checkTyVars $2 `thenP` \ args ->
- returnP ([HsClassP $1 args], $4, $5) }
- | qtycon tyvars '=>' tycon tyvars {% checkTyVars $2 `thenP` \ args ->
- returnP ([HsClassP $1 args], $4, $5) }
- | tycon tyvars { ([], $1, $2) }
+ : '(' comma_types1 ')' '=>' tycon tv_bndrs {% mapP checkPred $2 `thenP` \ cxt ->
+ returnP (cxt, $5, $6) }
+ | qtycon atypes1 '=>' tycon atypes0 {% checkTyVars $5 `thenP` \ tvs ->
+ returnP ([HsClassP $1 $2], $4, tvs) }
+ | qtycon atypes0 {% checkTyVars $2 `thenP` \ tvs ->
+ returnP ([], $1, tvs) }
+ -- We have to have qtycon in this production to avoid s/r conflicts
+ -- with the previous one. The renamer will complain if we use
+ -- a qualified tycon.
decls :: { [RdrBinding] }
: decls ';' decl { $3 : $1 }
decls :: { [RdrBinding] }
: decls ';' decl { $3 : $1 }
| sigtypes ',' sigtype { $3 : $1 }
sigtype :: { RdrNameHsType }
| sigtypes ',' sigtype { $3 : $1 }
sigtype :: { RdrNameHsType }
- : ctype { (mkHsForAllTy Nothing [] $1) }
+ : ctype { mkHsForAllTy Nothing [] $1 }
sig_vars :: { [RdrName] }
: sig_vars ',' var { $3 : $1 }
sig_vars :: { [RdrName] }
: sig_vars ',' var { $3 : $1 }
-- A ctype is a for-all type
ctype :: { RdrNameHsType }
-- A ctype is a for-all type
ctype :: { RdrNameHsType }
- : 'forall' tyvars '.' ctype { mkHsForAllTy (Just $2) [] $4 }
+ : 'forall' tv_bndrs '.' ctype { mkHsForAllTy (Just $2) [] $4 }
| context '=>' type { mkHsForAllTy Nothing $1 $3 }
-- A type of form (context => type) is an *implicit* HsForAllTy
| type { $1 }
| context '=>' type { mkHsForAllTy Nothing $1 $3 }
-- A type of form (context => type) is an *implicit* HsForAllTy
| type { $1 }
| atype tyconop atype { HsOpTy $1 $2 $3 }
btype :: { RdrNameHsType }
| atype tyconop atype { HsOpTy $1 $2 $3 }
btype :: { RdrNameHsType }
- : btype atype { (HsAppTy $1 $2) }
+ : btype atype { HsAppTy $1 $2 }
| atype { $1 }
atype :: { RdrNameHsType }
: gtycon { HsTyVar $1 }
| tyvar { HsTyVar $1 }
| atype { $1 }
atype :: { RdrNameHsType }
: gtycon { HsTyVar $1 }
| tyvar { HsTyVar $1 }
- | '(' type ',' types ')' { HsTupleTy (mkHsTupCon tcName Boxed ($2:$4)) ($2 : reverse $4) }
- | '(#' types '#)' { HsTupleTy (mkHsTupCon tcName Unboxed $2) (reverse $2) }
+ | '(' type ',' comma_types1 ')' { HsTupleTy (mkHsTupCon tcName Boxed ($2:$4)) ($2:$4) }
+ | '(#' comma_types1 '#)' { HsTupleTy (mkHsTupCon tcName Unboxed $2) $2 }
| '[' type ']' { HsListTy $2 }
| '[:' type ':]' { HsPArrTy $2 }
| '(' ctype ')' { $2 }
| '[' type ']' { HsListTy $2 }
| '[:' type ':]' { HsPArrTy $2 }
| '(' ctype ')' { $2 }
+ | '(' ctype '::' kind ')' { HsKindSig $2 $4 }
-- Generics
| INTEGER { HsNumTy $1 }
-- Generics
| INTEGER { HsNumTy $1 }
inst_type :: { RdrNameHsType }
: ctype {% checkInstType $1 }
inst_type :: { RdrNameHsType }
: ctype {% checkInstType $1 }
-types0 :: { [RdrNameHsType] }
- : types { reverse $1 }
+comma_types0 :: { [RdrNameHsType] }
+ : comma_types1 { $1 }
-types :: { [RdrNameHsType] }
+comma_types1 :: { [RdrNameHsType] }
- | types ',' type { $3 : $1 }
-
-simpletype :: { (RdrName, [RdrNameHsTyVar]) }
- : tycon tyvars { ($1, reverse $2) }
+ | type ',' comma_types1 { $1 : $3 }
-tyvars :: { [RdrNameHsTyVar] }
- : tyvar tyvars { UserTyVar $1 : $2 }
+atypes0 :: { [RdrNameHsType] }
+ : atypes1 { $1 }
+atypes1 :: { [RdrNameHsType] }
+ : atype { [$1] }
+ | atype atypes1 { $1 : $2 }
+
+tv_bndrs :: { [RdrNameHsTyVar] }
+ : tv_bndr tv_bndrs { $1 : $2 }
+ | {- empty -} { [] }
+
+tv_bndr :: { RdrNameHsTyVar }
+ : tyvar { UserTyVar $1 }
+ | '(' tyvar '::' kind ')' { IfaceTyVar $2 $4 }
+
fds :: { [([RdrName], [RdrName])] }
: {- empty -} { [] }
| '|' fds1 { reverse $2 }
fds :: { [([RdrName], [RdrName])] }
: {- empty -} { [] }
| '|' fds1 { reverse $2 }
| varids0 tyvar { $2 : $1 }
-----------------------------------------------------------------------------
| varids0 tyvar { $2 : $1 }
-----------------------------------------------------------------------------
+-- Kinds
+
+kind :: { Kind }
+ : akind { $1 }
+ | akind '->' kind { mkArrowKind $1 $3 }
+
+akind :: { Kind }
+ : '*' { liftedTypeKind }
+ | '(' kind ')' { $2 }
+
+
+-----------------------------------------------------------------------------
-- Datatype declarations
newconstr :: { RdrNameConDecl }
-- Datatype declarations
newconstr :: { RdrNameConDecl }
{ mkConDecl (fst $3) $2 [] (snd $3) $1 }
forall :: { [RdrNameHsTyVar] }
{ mkConDecl (fst $3) $2 [] (snd $3) $1 }
forall :: { [RdrNameHsTyVar] }
- : 'forall' tyvars '.' { $2 }
+ : 'forall' tv_bndrs '.' { $2 }
| {- empty -} { [] }
constr_stuff :: { (RdrName, RdrNameConDetails) }
| {- empty -} { [] }
constr_stuff :: { (RdrName, RdrNameConDetails) }
| aexp { $1 }
aexps0 :: { [RdrNameHsExpr] }
| aexp { $1 }
aexps0 :: { [RdrNameHsExpr] }
- : aexps { (reverse $1) }
aexps :: { [RdrNameHsExpr] }
: aexps aexp { $2 : $1 }
aexps :: { [RdrNameHsExpr] }
: aexps aexp { $2 : $1 }
ralt :: { [RdrNameGRHS] }
: '->' srcloc exp { [GRHS [ResultStmt $3 $2] $2] }
ralt :: { [RdrNameGRHS] }
: '->' srcloc exp { [GRHS [ResultStmt $3 $2] $2] }
- | gdpats { (reverse $1) }
+ | gdpats { reverse $1 }
gdpats :: { [RdrNameGRHS] }
: gdpats gdpat { $2 : $1 }
gdpats :: { [RdrNameGRHS] }
: gdpats gdpat { $2 : $1 }
| tycon { $1 }
gtycon :: { RdrName }
| tycon { $1 }
gtycon :: { RdrName }
- : tycon { $1 }
- | qtycon { $1 }
- | '(' tyconop ')' { $2 }
| '(' qtyconop ')' { $2 }
| '(' ')' { unitTyCon_RDR }
| '(' '->' ')' { funTyCon_RDR }
| '(' qtyconop ')' { $2 }
| '(' ')' { unitTyCon_RDR }
| '(' '->' ')' { funTyCon_RDR }
| '[:' ':]' { parrTyCon_RDR }
| '(' commas ')' { tupleTyCon_RDR $2 }
| '[:' ':]' { parrTyCon_RDR }
| '(' commas ')' { tupleTyCon_RDR $2 }
+gcon :: { RdrName } -- Data constructor namespace
: '(' ')' { unitCon_RDR }
| '[' ']' { nilCon_RDR }
| '(' commas ')' { tupleCon_RDR $2 }
: '(' ')' { unitCon_RDR }
| '[' ']' { nilCon_RDR }
| '(' commas ')' { tupleCon_RDR $2 }
special_sym :: { UserFS }
special_sym : '!' { SLIT("!") }
| '.' { SLIT(".") }
special_sym :: { UserFS }
special_sym : '!' { SLIT("!") }
| '.' { SLIT(".") }
-----------------------------------------------------------------------------
-- Literals
-----------------------------------------------------------------------------
-- Literals
tyconop :: { RdrName }
: CONSYM { mkUnqual tcClsName $1 }
tyconop :: { RdrName }
: CONSYM { mkUnqual tcClsName $1 }
-qtycon :: { RdrName } -- Just the qualified kind
+qtycon :: { RdrName } -- Qualified or unqualified
: QCONID { mkQual tcClsName $1 }
: QCONID { mkQual tcClsName $1 }
-qtyconop :: { RdrName } -- Just the qualified kind
+qtyconop :: { RdrName } -- Qualified or unqualified
: QCONSYM { mkQual tcClsName $1 }
: QCONSYM { mkQual tcClsName $1 }
commas :: { Int }
: commas ',' { $1 + 1 }
commas :: { Int }
: commas ',' { $1 + 1 }
extract_ty (HsFunTy ty1 ty2) acc = extract_ty ty1 (extract_ty ty2 acc)
extract_ty (HsPredTy p) acc = extract_pred p acc
extract_ty (HsTyVar tv) acc = tv : acc
extract_ty (HsFunTy ty1 ty2) acc = extract_ty ty1 (extract_ty ty2 acc)
extract_ty (HsPredTy p) acc = extract_pred p acc
extract_ty (HsTyVar tv) acc = tv : acc
-extract_ty (HsForAllTy Nothing ctxt ty) acc = extract_ctxt ctxt (extract_ty ty acc)
+extract_ty (HsForAllTy Nothing cx ty) acc = extract_ctxt cx (extract_ty ty acc)
-extract_ty (HsOpTy ty1 nam ty2) acc = extract_ty ty1 (extract_ty ty2 acc)
+extract_ty (HsOpTy ty1 nam ty2) acc = extract_ty ty1 (extract_ty ty2 acc)
extract_ty (HsNumTy num) acc = acc
extract_ty (HsNumTy num) acc = acc
+extract_ty (HsKindSig ty k) acc = extract_ty ty acc
extract_ty (HsForAllTy (Just tvs) ctxt ty)
acc = acc ++
(filter (`notElem` locals) $
extract_ty (HsForAllTy (Just tvs) ctxt ty)
acc = acc ++
(filter (`notElem` locals) $
'=>' { ITdarrow }
'-' { ITminus }
'!' { ITbang }
'=>' { ITdarrow }
'-' { ITminus }
'!' { ITbang }
'{' { ITocurly } -- special symbols
'}' { ITccurly }
'{' { ITocurly } -- special symbols
'}' { ITccurly }
| akind '->' kind { mkArrowKind $1 $3 }
akind :: { Kind }
| akind '->' kind { mkArrowKind $1 $3 }
akind :: { Kind }
- : VARSYM { if $1 == SLIT("*") then
- liftedTypeKind
- else if $1 == SLIT("?") then
+ : '*' { liftedTypeKind }
+ | VARSYM { if $1 == SLIT("?") then
openTypeKind
else if $1 == SLIT("\36") then
usageTypeKind -- dollar
openTypeKind
else if $1 == SLIT("\36") then
usageTypeKind -- dollar
unitNameSet tycon
get (HsNumTy n) = emptyNameSet
get (HsTyVar tv) = unitNameSet tv
unitNameSet tycon
get (HsNumTy n) = emptyNameSet
get (HsTyVar tv) = unitNameSet tv
+ get (HsKindSig ty k) = get ty
get (HsForAllTy (Just tvs)
ctxt ty) = (extractHsCtxtTyNames ctxt `unionNameSets` get ty)
`minusNameSet`
get (HsForAllTy (Just tvs)
ctxt ty) = (extractHsCtxtTyNames ctxt `unionNameSets` get ty)
`minusNameSet`
= rnHsType doc ty `thenRn` \ ty' ->
returnRn (HsListTy ty')
= rnHsType doc ty `thenRn` \ ty' ->
returnRn (HsListTy ty')
+rnHsType doc (HsKindSig ty k)
+ = rnHsType doc ty `thenRn` \ ty' ->
+ returnRn (HsKindSig ty' k)
+
rnHsType doc (HsPArrTy ty)
= rnHsType doc ty `thenRn` \ ty' ->
returnRn (HsPArrTy ty')
rnHsType doc (HsPArrTy ty)
= rnHsType doc ty `thenRn` \ ty' ->
returnRn (HsPArrTy ty')
kcHsType :: RenamedHsType -> TcM TcKind
kcHsType (HsTyVar name) = kcTyVar name
kcHsType :: RenamedHsType -> TcM TcKind
kcHsType (HsTyVar name) = kcTyVar name
+kcHsType (HsKindSig ty k)
+ = kcHsType ty `thenTc` \ k' ->
+ unifyKind k k' `thenTc_`
+ returnTc k
+
kcHsType (HsListTy ty)
= kcLiftedType ty `thenTc` \ tau_ty ->
returnTc liftedTypeKind
kcHsType (HsListTy ty)
= kcLiftedType ty `thenTc` \ tau_ty ->
returnTc liftedTypeKind
tc_type ty@(HsTyVar name)
= tc_app ty []
tc_type ty@(HsTyVar name)
= tc_app ty []
+tc_type (HsKindSig ty k)
+ = tc_type ty -- Kind checking done already
+
tc_type (HsListTy ty)
= tc_type ty `thenTc` \ tau_ty ->
returnTc (mkListTy tau_ty)
tc_type (HsListTy ty)
= tc_type ty `thenTc` \ tau_ty ->
returnTc (mkListTy tau_ty)