1-----------------------------------------------------------------------------
3-- Module : PureScript.TypeChecker
4-- Copyright : (c) Phil Freeman 2013
7-- Maintainer : Phil Freeman <paf31@cantab.net>
8-- Stability : experimental
13-----------------------------------------------------------------------------
15{-# LANGUAGE FlexibleInstances #-}
17module PureScript.TypeChecker (
22import PureScript.TypeChecker.Monad as T
23import PureScript.TypeChecker.Kinds as T
24import PureScript.TypeChecker.Types as T
25import PureScript.TypeChecker.Synonyms as T
30import qualified Data.Map as M
32import PureScript.Values
33import PureScript.Types
34import PureScript.Names
35import PureScript.Kinds
36import PureScript.Declarations
38import Control.Monad (forM_)
39import Control.Monad.State
40import Control.Monad.Error
42typeCheckAll :: [Declaration] -> Check ()
43typeCheckAll [] = return ()
44typeCheckAll (DataDeclaration name args dctors : rest) = do
45 rethrow (("Error in type constructor " ++ name ++ ": ") ++) $ do
47 guardWith (name ++ " is already defined") $ not $ M.member name (types env)
48 ctorKind <- kindsOf (Just name) args (mapMaybe snd dctors)
49 putEnv $ env { types = M.insert name (ctorKind, Data) (types env) }
50 forM_ dctors $ \(dctor, maybeTy) ->
51 rethrow (("Error in data constructor " ++ name ++ ": ") ++) $ do
53 guardWith (dctor ++ " is already defined") $ not $ M.member dctor (dataConstructors env')
54 let retTy = foldl TypeApp (TypeConstructor name) (map TypeVar args)
55 let dctorTy = maybe retTy (\ty -> Function [ty] retTy) maybeTy
56 let polyType = PolyType args dctorTy
57 putEnv $ env' { dataConstructors = M.insert dctor polyType (dataConstructors env') }
59typeCheckAll (TypeSynonymDeclaration name args ty : rest) = do
60 rethrow (("Error in type synonym " ++ name ++ ": ") ++) $ do
62 guardWith (name ++ " is already defined") $ not $ M.member name (types env)
63 kind <- kindsOf (Just name) args [ty]
64 putEnv $ env { types = M.insert name (kind, TypeSynonym) (types env)
65 , typeSynonyms = M.insert name (args, ty) (typeSynonyms env) }
67typeCheckAll (TypeDeclaration name ty : ValueDeclaration name' val : rest) | name == name' =
68 typeCheckAll (ValueDeclaration name (TypedValue val ty) : rest)
69typeCheckAll (TypeDeclaration name _ : _) = throwError $ "Orphan type declaration for " ++ show name
70typeCheckAll (ValueDeclaration name val : rest) = do
71 rethrow (("Error in declaration " ++ show name ++ ": ") ++) $ do
73 case M.lookup name (names env) of
74 Just ty -> throwError $ show name ++ " is already defined"
77 putEnv (env { names = M.insert name (ty, Value) (names env) })
79typeCheckAll (ExternDataDeclaration name kind : rest) = do
81 guardWith (name ++ " is already defined") $ not $ M.member name (types env)
82 putEnv $ env { types = M.insert name (kind, TypeSynonym) (types env) }
84typeCheckAll (ExternDeclaration name ty : rest) = do
85 rethrow (("Error in extern declaration " ++ show name ++ ": ") ++) $ do
88 guardWith "Expected kind *" $ kind == Star
89 case M.lookup name (names env) of
90 Just _ -> throwError $ show name ++ " is already defined"
91 Nothing -> putEnv (env { names = M.insert name (ty, Extern) (names env) })
93typeCheckAll (FixityDeclaration _ name : rest) = do
96 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