HaRe-0.6: tools/base/Modules/TypedIds.hs
module TypedIds where
import Maybe(isJust)
import Data.Generics
{-+
Haskell declaration introduce names in two name spaces. Type classes and
types live in one name space. Values (functions, data constructors) live
in another name space.
-}
data NameSpace = ClassOrTypeNames | ValueNames deriving (Eq,Ord,Show, Data, Typeable)
{-+
Identifiers can denote many different types of entities. It is clear from
the defining occurence of an identifier what type of entity it denotes.
The type #IdTy# can be seen as a refinement of #NameSpace#.
From the use of an identifier, we can tell what name space it refers
to, but not the exact type of entity, hence the need for two different types.
-}
data IdTy i
= Value
| FieldOf i (TypeInfo i)
| MethodOf i Int [i] -- name of class, number of superclasses, names of all methods
| ConstrOf i (TypeInfo i)
| Class Int [i] -- number of superclasses, names of all methods
| Type (TypeInfo i)
| Assertion -- P-Logic assertion name
| Property -- P-Logic property name
deriving (Eq,Ord,Show,Read, Data, Typeable)
-- These structures contain a lot of redundancy, so we shouldn't really
-- use any comparison operations on them.
data ConInfo i = ConInfo
{ conName :: i
, conArity :: Int
, conFields :: Maybe [i] -- length agrees with conArity
} deriving (Eq,Ord,Show,Read, Data, Typeable)
data DefTy = Newtype | Data | Synonym | Primitive
deriving (Eq,Ord,Show,Read, Data, Typeable)
data TypeInfo i = TypeInfo
{ defType :: Maybe DefTy
, constructors :: [ConInfo i]
, fields :: [i]
} deriving (Eq,Ord,Show,Read, Data, Typeable)
blankTypeInfo = TypeInfo { defType = Nothing, constructors = [], fields = [] }
instance Functor ConInfo where
fmap f c = c { conName = f (conName c),
conFields = fmap (map f) (conFields c) }
instance Functor TypeInfo where
fmap f t = t { constructors = map (fmap f) (constructors t)
, fields = map f (fields t)
}
instance Functor IdTy where
fmap f (FieldOf x tyInfo) = FieldOf (f x) (fmap f tyInfo)
fmap f (MethodOf x n xs) = MethodOf (f x) n (map f xs)
fmap f (ConstrOf t tyInfo) = ConstrOf (f t) (fmap f tyInfo)
fmap _ Value = Value
fmap f (Class n xs) = Class n (f `map` xs)
fmap f (Type tyInfo) = Type (fmap f tyInfo)
fmap _ Assertion = Assertion
fmap _ Property = Property
class HasNameSpace t where
namespace :: t -> NameSpace
instance HasNameSpace (IdTy id) where
namespace Value = ValueNames
namespace (FieldOf {}) = ValueNames
namespace (MethodOf {}) = ValueNames
namespace (ConstrOf {}) = ValueNames
namespace (Class {}) = ClassOrTypeNames
namespace (Type {}) = ClassOrTypeNames
namespace Assertion = ValueNames -- hmm
namespace Property = ValueNames -- hmm
-- owner :: IdTy i -> Maybe i
owner (FieldOf dt _) = Just dt
owner (MethodOf cl _ _) = Just cl
owner (ConstrOf dt _) = Just dt
owner _ = Nothing
-- isSubordinate :: IdTy i -> Bool
isSubordinate = isJust . owner
-- belongsTo :: idTy i -> i -> Bool
idty `belongsTo` t = owner idty == Just t
isAssertion Assertion = True
isAssertion Property = True
isAssertion _ = False
isClassOrType,isValue :: HasNameSpace t => t -> Bool
isClassOrType = (== ClassOrTypeNames) . namespace
isValue = (== ValueNames) . namespace
class HasIdTy i t | t->i where
idTy :: t -> IdTy i
instance HasIdTy i (IdTy i) where idTy = id
--instance HasNameSpace NameSpace where namespace = id