1-- This module contains checks to be run *after* type inference has
2-- completed successfully. At that point we still need to do occurs
3-- checks and ensure that `main` has an acceptable type.
4module Type.ExtraChecks (extraChecks) where
6import Control.Applicative ((<$>),(<*>))
7import qualified Data.Map as Map
8import qualified Data.UnionFind.IO as UF
9import Type.Type ( Variable, structure, Term1(..), toSrcType )
10import Type.State (Env)
11import qualified Type.Alias as Alias
12import Text.PrettyPrint as P
13import SourceSyntax.PrettyPrint (pretty)
14import SourceSyntax.Type (Type)
15import qualified Data.Traversable as Traverse
17extraChecks :: Alias.Rules -> Env -> IO (Either [P.Doc] (Map.Map String Type))
18extraChecks rules env = do
19 eitherEnv <- occursCheck env
21 Left errs -> return $ Left errs
23 mainCheck rules <$> Traverse.traverse toSrcType env'
26mainCheck :: Alias.Rules -> (Map.Map String Type) -> Either [P.Doc] (Map.Map String Type)
28 let acceptable = ["Graphics.Element.Element","Signal.Signal Graphics.Element.Element"] in
29 case Map.lookup "main" env of
32 | P.render (pretty (Alias.canonicalRealias (fst rules) tipe)) `elem` acceptable ->
35 Left [ P.vcat [ P.text "Type Error:"
36 , P.text "Bad type for 'main'. It must have type Element or a (Signal Element)"
37 , P.text "Instead 'main' has type:\n"
38 , P.nest 4 . pretty $ Alias.realias rules tipe
42occursCheck :: Env -> IO (Either [P.Doc] Env)
44 errors <- concat <$> mapM isFinite (Map.toList env)
45 return $ if null errors then Right env else Left errors
47isFinite :: (String, Variable) -> IO [P.Doc]
49 do varIsFinite <- go [] var
53 False -> [ P.vcat [ P.text "Type Error:"
54 , P.text $ "Cannot construct infinite type for '" ++ name ++ "'\n"
58 go :: [Variable] -> Variable -> IO Bool
60 let check = go (var:seen) in
61 case var `elem` seen of
64 desc <- UF.descriptor var
65 case structure desc of
66 Nothing -> return True
69 App1 a b -> (&&) <$> check a <*> check b
70 Fun1 a b -> (&&) <$> check a <*> check b
72 EmptyRecord1 -> return True
73 Record1 fields ext -> and <$> mapM check (ext : concat (Map.elems fields))
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