{-# LANGUAGE CPP #-}
module PatSyn (
PatSyn, mkPatSyn,
patSynName, patSynArity, patSynIsInfix,
patSynArgs,
patSynMatcher, patSynBuilder,
patSynUnivTyVarBinders, patSynExTyVars, patSynExTyVarBinders, patSynSig,
patSynInstArgTys, patSynInstResTy, patSynFieldLabels,
patSynFieldType,
updatePatSynIds, pprPatSynType
) where
#include "HsVersions.h"
import GhcPrelude
import Type
import Name
import Outputable
import Unique
import Util
import BasicTypes
import Var
import FieldLabel
import qualified Data.Data as Data
import Data.Function
import Data.List
data PatSyn
= MkPatSyn {
PatSyn -> Name
psName :: Name,
PatSyn -> Unique
psUnique :: Unique,
PatSyn -> [Type]
psArgs :: [Type],
PatSyn -> Arity
psArity :: Arity,
PatSyn -> Bool
psInfix :: Bool,
PatSyn -> [FieldLabel]
psFieldLabels :: [FieldLabel],
PatSyn -> [TyVarBinder]
psUnivTyVars :: [TyVarBinder],
PatSyn -> [Type]
psReqTheta :: ThetaType,
PatSyn -> [TyVarBinder]
psExTyVars :: [TyVarBinder],
PatSyn -> [Type]
psProvTheta :: ThetaType,
PatSyn -> Type
psResultTy :: Type,
PatSyn -> (Id, Bool)
psMatcher :: (Id, Bool),
PatSyn -> Maybe (Id, Bool)
psBuilder :: Maybe (Id, Bool)
}
instance Eq PatSyn where
== :: PatSyn -> PatSyn -> Bool
(==) = Unique -> Unique -> Bool
forall a. Eq a => a -> a -> Bool
(==) (Unique -> Unique -> Bool)
-> (PatSyn -> Unique) -> PatSyn -> PatSyn -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` PatSyn -> Unique
forall a. Uniquable a => a -> Unique
getUnique
/= :: PatSyn -> PatSyn -> Bool
(/=) = Unique -> Unique -> Bool
forall a. Eq a => a -> a -> Bool
(/=) (Unique -> Unique -> Bool)
-> (PatSyn -> Unique) -> PatSyn -> PatSyn -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` PatSyn -> Unique
forall a. Uniquable a => a -> Unique
getUnique
instance Uniquable PatSyn where
getUnique :: PatSyn -> Unique
getUnique = PatSyn -> Unique
psUnique
instance NamedThing PatSyn where
getName :: PatSyn -> Name
getName = PatSyn -> Name
patSynName
instance Outputable PatSyn where
ppr :: PatSyn -> SDoc
ppr = Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Name -> SDoc) -> (PatSyn -> Name) -> PatSyn -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatSyn -> Name
forall a. NamedThing a => a -> Name
getName
instance OutputableBndr PatSyn where
pprInfixOcc :: PatSyn -> SDoc
pprInfixOcc = Name -> SDoc
forall a. (Outputable a, NamedThing a) => a -> SDoc
pprInfixName (Name -> SDoc) -> (PatSyn -> Name) -> PatSyn -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatSyn -> Name
forall a. NamedThing a => a -> Name
getName
pprPrefixOcc :: PatSyn -> SDoc
pprPrefixOcc = Name -> SDoc
forall a. NamedThing a => a -> SDoc
pprPrefixName (Name -> SDoc) -> (PatSyn -> Name) -> PatSyn -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatSyn -> Name
forall a. NamedThing a => a -> Name
getName
instance Data.Data PatSyn where
toConstr :: PatSyn -> Constr
toConstr _ = String -> Constr
abstractConstr "PatSyn"
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PatSyn
gunfold _ _ = String -> Constr -> c PatSyn
forall a. HasCallStack => String -> a
error "gunfold"
dataTypeOf :: PatSyn -> DataType
dataTypeOf _ = String -> DataType
mkNoRepType "PatSyn"
mkPatSyn :: Name
-> Bool
-> ([TyVarBinder], ThetaType)
-> ([TyVarBinder], ThetaType)
-> [Type]
-> Type
-> (Id, Bool)
-> Maybe (Id, Bool)
-> [FieldLabel]
-> PatSyn
mkPatSyn :: Name
-> Bool
-> ([TyVarBinder], [Type])
-> ([TyVarBinder], [Type])
-> [Type]
-> Type
-> (Id, Bool)
-> Maybe (Id, Bool)
-> [FieldLabel]
-> PatSyn
mkPatSyn name :: Name
name declared_infix :: Bool
declared_infix
(univ_tvs :: [TyVarBinder]
univ_tvs, req_theta :: [Type]
req_theta)
(ex_tvs :: [TyVarBinder]
ex_tvs, prov_theta :: [Type]
prov_theta)
orig_args :: [Type]
orig_args
orig_res_ty :: Type
orig_res_ty
matcher :: (Id, Bool)
matcher builder :: Maybe (Id, Bool)
builder field_labels :: [FieldLabel]
field_labels
= MkPatSyn :: Name
-> Unique
-> [Type]
-> Arity
-> Bool
-> [FieldLabel]
-> [TyVarBinder]
-> [Type]
-> [TyVarBinder]
-> [Type]
-> Type
-> (Id, Bool)
-> Maybe (Id, Bool)
-> PatSyn
MkPatSyn {psName :: Name
psName = Name
name, psUnique :: Unique
psUnique = Name -> Unique
forall a. Uniquable a => a -> Unique
getUnique Name
name,
psUnivTyVars :: [TyVarBinder]
psUnivTyVars = [TyVarBinder]
univ_tvs,
psExTyVars :: [TyVarBinder]
psExTyVars = [TyVarBinder]
ex_tvs,
psProvTheta :: [Type]
psProvTheta = [Type]
prov_theta, psReqTheta :: [Type]
psReqTheta = [Type]
req_theta,
psInfix :: Bool
psInfix = Bool
declared_infix,
psArgs :: [Type]
psArgs = [Type]
orig_args,
psArity :: Arity
psArity = [Type] -> Arity
forall (t :: * -> *) a. Foldable t => t a -> Arity
length [Type]
orig_args,
psResultTy :: Type
psResultTy = Type
orig_res_ty,
psMatcher :: (Id, Bool)
psMatcher = (Id, Bool)
matcher,
psBuilder :: Maybe (Id, Bool)
psBuilder = Maybe (Id, Bool)
builder,
psFieldLabels :: [FieldLabel]
psFieldLabels = [FieldLabel]
field_labels
}
patSynName :: PatSyn -> Name
patSynName :: PatSyn -> Name
patSynName = PatSyn -> Name
psName
patSynIsInfix :: PatSyn -> Bool
patSynIsInfix :: PatSyn -> Bool
patSynIsInfix = PatSyn -> Bool
psInfix
patSynArity :: PatSyn -> Arity
patSynArity :: PatSyn -> Arity
patSynArity = PatSyn -> Arity
psArity
patSynArgs :: PatSyn -> [Type]
patSynArgs :: PatSyn -> [Type]
patSynArgs = PatSyn -> [Type]
psArgs
patSynFieldLabels :: PatSyn -> [FieldLabel]
patSynFieldLabels :: PatSyn -> [FieldLabel]
patSynFieldLabels = PatSyn -> [FieldLabel]
psFieldLabels
patSynFieldType :: PatSyn -> FieldLabelString -> Type
patSynFieldType :: PatSyn -> FieldLabelString -> Type
patSynFieldType ps :: PatSyn
ps label :: FieldLabelString
label
= case ((FieldLabel, Type) -> Bool)
-> [(FieldLabel, Type)] -> Maybe (FieldLabel, Type)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ((FieldLabelString -> FieldLabelString -> Bool
forall a. Eq a => a -> a -> Bool
== FieldLabelString
label) (FieldLabelString -> Bool)
-> ((FieldLabel, Type) -> FieldLabelString)
-> (FieldLabel, Type)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FieldLabel -> FieldLabelString
forall a. FieldLbl a -> FieldLabelString
flLabel (FieldLabel -> FieldLabelString)
-> ((FieldLabel, Type) -> FieldLabel)
-> (FieldLabel, Type)
-> FieldLabelString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FieldLabel, Type) -> FieldLabel
forall a b. (a, b) -> a
fst) (PatSyn -> [FieldLabel]
psFieldLabels PatSyn
ps [FieldLabel] -> [Type] -> [(FieldLabel, Type)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` PatSyn -> [Type]
psArgs PatSyn
ps) of
Just (_, ty :: Type
ty) -> Type
ty
Nothing -> String -> SDoc -> Type
forall a. HasCallStack => String -> SDoc -> a
pprPanic "dataConFieldType" (PatSyn -> SDoc
forall a. Outputable a => a -> SDoc
ppr PatSyn
ps SDoc -> SDoc -> SDoc
<+> FieldLabelString -> SDoc
forall a. Outputable a => a -> SDoc
ppr FieldLabelString
label)
patSynUnivTyVarBinders :: PatSyn -> [TyVarBinder]
patSynUnivTyVarBinders :: PatSyn -> [TyVarBinder]
patSynUnivTyVarBinders = PatSyn -> [TyVarBinder]
psUnivTyVars
patSynExTyVars :: PatSyn -> [TyVar]
patSynExTyVars :: PatSyn -> [Id]
patSynExTyVars ps :: PatSyn
ps = [TyVarBinder] -> [Id]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars (PatSyn -> [TyVarBinder]
psExTyVars PatSyn
ps)
patSynExTyVarBinders :: PatSyn -> [TyVarBinder]
patSynExTyVarBinders :: PatSyn -> [TyVarBinder]
patSynExTyVarBinders = PatSyn -> [TyVarBinder]
psExTyVars
patSynSig :: PatSyn -> ([TyVar], ThetaType, [TyVar], ThetaType, [Type], Type)
patSynSig :: PatSyn -> ([Id], [Type], [Id], [Type], [Type], Type)
patSynSig (MkPatSyn { psUnivTyVars :: PatSyn -> [TyVarBinder]
psUnivTyVars = [TyVarBinder]
univ_tvs, psExTyVars :: PatSyn -> [TyVarBinder]
psExTyVars = [TyVarBinder]
ex_tvs
, psProvTheta :: PatSyn -> [Type]
psProvTheta = [Type]
prov, psReqTheta :: PatSyn -> [Type]
psReqTheta = [Type]
req
, psArgs :: PatSyn -> [Type]
psArgs = [Type]
arg_tys, psResultTy :: PatSyn -> Type
psResultTy = Type
res_ty })
= ([TyVarBinder] -> [Id]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars [TyVarBinder]
univ_tvs, [Type]
req, [TyVarBinder] -> [Id]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars [TyVarBinder]
ex_tvs, [Type]
prov, [Type]
arg_tys, Type
res_ty)
patSynMatcher :: PatSyn -> (Id,Bool)
patSynMatcher :: PatSyn -> (Id, Bool)
patSynMatcher = PatSyn -> (Id, Bool)
psMatcher
patSynBuilder :: PatSyn -> Maybe (Id, Bool)
patSynBuilder :: PatSyn -> Maybe (Id, Bool)
patSynBuilder = PatSyn -> Maybe (Id, Bool)
psBuilder
updatePatSynIds :: (Id -> Id) -> PatSyn -> PatSyn
updatePatSynIds :: (Id -> Id) -> PatSyn -> PatSyn
updatePatSynIds tidy_fn :: Id -> Id
tidy_fn ps :: PatSyn
ps@(MkPatSyn { psMatcher :: PatSyn -> (Id, Bool)
psMatcher = (Id, Bool)
matcher, psBuilder :: PatSyn -> Maybe (Id, Bool)
psBuilder = Maybe (Id, Bool)
builder })
= PatSyn
ps { psMatcher :: (Id, Bool)
psMatcher = (Id, Bool) -> (Id, Bool)
forall b. (Id, b) -> (Id, b)
tidy_pr (Id, Bool)
matcher, psBuilder :: Maybe (Id, Bool)
psBuilder = ((Id, Bool) -> (Id, Bool)) -> Maybe (Id, Bool) -> Maybe (Id, Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Id, Bool) -> (Id, Bool)
forall b. (Id, b) -> (Id, b)
tidy_pr Maybe (Id, Bool)
builder }
where
tidy_pr :: (Id, b) -> (Id, b)
tidy_pr (id :: Id
id, dummy :: b
dummy) = (Id -> Id
tidy_fn Id
id, b
dummy)
patSynInstArgTys :: PatSyn -> [Type] -> [Type]
patSynInstArgTys :: PatSyn -> [Type] -> [Type]
patSynInstArgTys (MkPatSyn { psName :: PatSyn -> Name
psName = Name
name, psUnivTyVars :: PatSyn -> [TyVarBinder]
psUnivTyVars = [TyVarBinder]
univ_tvs
, psExTyVars :: PatSyn -> [TyVarBinder]
psExTyVars = [TyVarBinder]
ex_tvs, psArgs :: PatSyn -> [Type]
psArgs = [Type]
arg_tys })
inst_tys :: [Type]
inst_tys
= ASSERT2( tyvars `equalLength` inst_tys
, text "patSynInstArgTys" <+> ppr name $$ ppr tyvars $$ ppr inst_tys )
(Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (HasCallStack => [Id] -> [Type] -> Type -> Type
[Id] -> [Type] -> Type -> Type
substTyWith [Id]
tyvars [Type]
inst_tys) [Type]
arg_tys
where
tyvars :: [Id]
tyvars = [TyVarBinder] -> [Id]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars ([TyVarBinder]
univ_tvs [TyVarBinder] -> [TyVarBinder] -> [TyVarBinder]
forall a. [a] -> [a] -> [a]
++ [TyVarBinder]
ex_tvs)
patSynInstResTy :: PatSyn -> [Type] -> Type
patSynInstResTy :: PatSyn -> [Type] -> Type
patSynInstResTy (MkPatSyn { psName :: PatSyn -> Name
psName = Name
name, psUnivTyVars :: PatSyn -> [TyVarBinder]
psUnivTyVars = [TyVarBinder]
univ_tvs
, psResultTy :: PatSyn -> Type
psResultTy = Type
res_ty })
inst_tys :: [Type]
inst_tys
= ASSERT2( univ_tvs `equalLength` inst_tys
, text "patSynInstResTy" <+> ppr name $$ ppr univ_tvs $$ ppr inst_tys )
HasCallStack => [Id] -> [Type] -> Type -> Type
[Id] -> [Type] -> Type -> Type
substTyWith ([TyVarBinder] -> [Id]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars [TyVarBinder]
univ_tvs) [Type]
inst_tys Type
res_ty
pprPatSynType :: PatSyn -> SDoc
pprPatSynType :: PatSyn -> SDoc
pprPatSynType (MkPatSyn { psUnivTyVars :: PatSyn -> [TyVarBinder]
psUnivTyVars = [TyVarBinder]
univ_tvs, psReqTheta :: PatSyn -> [Type]
psReqTheta = [Type]
req_theta
, psExTyVars :: PatSyn -> [TyVarBinder]
psExTyVars = [TyVarBinder]
ex_tvs, psProvTheta :: PatSyn -> [Type]
psProvTheta = [Type]
prov_theta
, psArgs :: PatSyn -> [Type]
psArgs = [Type]
orig_args, psResultTy :: PatSyn -> Type
psResultTy = Type
orig_res_ty })
= [SDoc] -> SDoc
sep [ [TyVarBinder] -> SDoc
pprForAll [TyVarBinder]
univ_tvs
, [Type] -> SDoc
pprThetaArrowTy [Type]
req_theta
, Bool -> SDoc -> SDoc
ppWhen Bool
insert_empty_ctxt (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ SDoc -> SDoc
parens SDoc
empty SDoc -> SDoc -> SDoc
<+> SDoc
darrow
, Type -> SDoc
pprType Type
sigma_ty ]
where
sigma_ty :: Type
sigma_ty = [TyVarBinder] -> Type -> Type
mkForAllTys [TyVarBinder]
ex_tvs (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$
[Type] -> Type -> Type
mkFunTys [Type]
prov_theta (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$
[Type] -> Type -> Type
mkFunTys [Type]
orig_args Type
orig_res_ty
insert_empty_ctxt :: Bool
insert_empty_ctxt = [Type] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
req_theta Bool -> Bool -> Bool
&& Bool -> Bool
not ([Type] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
prov_theta Bool -> Bool -> Bool
&& [TyVarBinder] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TyVarBinder]
ex_tvs)