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
33import PureScript.Values
34import PureScript.Types
35import PureScript.Kinds
36import PureScript.Declarations
38import Control.Monad.State
39import Control.Monad.Error
41import qualified Data.Map as M
43typeCheckAll :: [Declaration] -> Check ()
44typeCheckAll [] = return ()
45typeCheckAll (DataDeclaration name args dctors : rest) = do
46 rethrow (("Error in type constructor " ++ name ++ ": ") ++) $ do
48 guardWith (name ++ " is already defined") $ not $ M.member name (types env)
49 ctorKind <- kindsOf (Just name) args (catMaybes $ map snd dctors)
50 putEnv $ env { types = M.insert name (ctorKind, Data) (types env) }
51 flip mapM_ dctors $ \(dctor, maybeTy) ->
52 rethrow (("Error in data constructor " ++ name ++ ": ") ++) $ do
54 guardWith (dctor ++ " is already defined") $ not $ flip M.member (dataConstructors env') dctor
55 let retTy = foldl TypeApp (TypeConstructor name) (map TypeVar args)
56 let dctorTy = maybe retTy (\ty -> Function [ty] retTy) maybeTy
57 let polyType = PolyType args dctorTy
58 putEnv $ env' { dataConstructors = M.insert dctor polyType (dataConstructors env') }
60typeCheckAll (TypeSynonymDeclaration name args ty : rest) = do
61 rethrow (("Error in type synonym " ++ name ++ ": ") ++) $ do
63 guardWith (name ++ " is already defined") $ not $ M.member name (types env)
64 kind <- kindsOf (Just name) args [ty]
65 putEnv $ env { types = M.insert name (kind, TypeSynonym) (types env)
66 , typeSynonyms = M.insert name (args, ty) (typeSynonyms env) }
68typeCheckAll (TypeDeclaration name ty : ValueDeclaration name' val : rest) | name == name' =
69 typeCheckAll (ValueDeclaration name (TypedValue val ty) : rest)
70typeCheckAll (TypeDeclaration name _ : _) = throwError $ "Orphan type declaration for " ++ show name
71typeCheckAll (ValueDeclaration name val : rest) = do
72 rethrow (("Error in declaration " ++ show name ++ ": ") ++) $ do
74 case M.lookup name (names env) of
75 Just ty -> throwError $ show name ++ " is already defined"
78 putEnv (env { names = M.insert name (ty, Value) (names env) })
80typeCheckAll (ExternDeclaration name ty : rest) = do
81 rethrow (("Error in extern declaration " ++ show name ++ ": ") ++) $ do
84 guardWith "Expected kind *" $ kind == Star
85 case M.lookup name (names env) of
86 Just _ -> throwError $ show name ++ " is already defined"
87 Nothing -> putEnv (env { names = M.insert name (ty, Extern) (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