1-----------------------------------------------------------------------------
3-- Module : PureScript.TypeChecker
4-- Copyright : (c) Phil Freeman 2013
7-- Maintainer : Phil Freeman <paf31@cantab.net>
8-- Stability : experimental
13-----------------------------------------------------------------------------
15{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleInstances #-}
17module PureScript.TypeChecker (
18 module PureScript.TypeChecker.Monad,
19 module PureScript.TypeChecker.Kinds,
20 module PureScript.TypeChecker.Types,
24import PureScript.TypeChecker.Monad
25import PureScript.TypeChecker.Kinds
26import PureScript.TypeChecker.Types
27import PureScript.TypeChecker.Synonyms
32import qualified Data.Map as M
34import PureScript.Values
35import PureScript.Types
36import PureScript.Names
37import PureScript.Kinds
38import PureScript.Declarations
40import Control.Monad.State
41import Control.Monad.Error
43import qualified Data.Map as M
45typeCheckAll :: [Declaration] -> Check ()
46typeCheckAll [] = return ()
47typeCheckAll (DataDeclaration name args dctors : rest) = do
48 rethrow (("Error in type constructor " ++ name ++ ": ") ++) $ do
50 guardWith (name ++ " is already defined") $ not $ M.member name (types env)
51 ctorKind <- kindsOf (Just name) args (catMaybes $ map snd dctors)
52 putEnv $ env { types = M.insert name (ctorKind, Data) (types env) }
53 flip mapM_ dctors $ \(dctor, maybeTy) ->
54 rethrow (("Error in data constructor " ++ name ++ ": ") ++) $ do
56 guardWith (dctor ++ " is already defined") $ not $ flip M.member (dataConstructors env') dctor
57 let retTy = foldl TypeApp (TypeConstructor name) (map TypeVar args)
58 let dctorTy = maybe retTy (\ty -> Function [ty] retTy) maybeTy
59 let polyType = PolyType args dctorTy
60 putEnv $ env' { dataConstructors = M.insert dctor polyType (dataConstructors env') }
62typeCheckAll (TypeSynonymDeclaration name args ty : rest) = do
63 rethrow (("Error in type synonym " ++ name ++ ": ") ++) $ do
65 guardWith (name ++ " is already defined") $ not $ M.member name (types env)
66 kind <- kindsOf (Just name) args [ty]
67 putEnv $ env { types = M.insert name (kind, TypeSynonym) (types env)
68 , typeSynonyms = M.insert name (args, ty) (typeSynonyms env) }
70typeCheckAll (TypeDeclaration name ty : ValueDeclaration name' val : rest) | name == name' =
71 typeCheckAll (ValueDeclaration name (TypedValue val ty) : rest)
72typeCheckAll (TypeDeclaration name _ : _) = throwError $ "Orphan type declaration for " ++ show name
73typeCheckAll (ValueDeclaration name val : rest) = do
74 rethrow (("Error in declaration " ++ show name ++ ": ") ++) $ do
76 case M.lookup name (names env) of
77 Just ty -> throwError $ show name ++ " is already defined"
80 putEnv (env { names = M.insert name (ty, Value) (names env) })
82typeCheckAll (ExternDataDeclaration name kind : rest) = do
84 guardWith (name ++ " is already defined") $ not $ M.member name (types env)
85 putEnv $ env { types = M.insert name (kind, TypeSynonym) (types env) }
87typeCheckAll (ExternDeclaration name ty : rest) = do
88 rethrow (("Error in extern declaration " ++ show name ++ ": ") ++) $ do
91 guardWith "Expected kind *" $ kind == Star
92 case M.lookup name (names env) of
93 Just _ -> throwError $ show name ++ " is already defined"
94 Nothing -> putEnv (env { names = M.insert name (ty, Extern) (names env) })
96typeCheckAll (FixityDeclaration _ name : rest) = do
99 guardWith ("Fixity declaration with no binding: " ++ name) $ M.member (Op name) $ names env
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list