1{-# OPTIONS_GHC -Wall #-}
3{-| This module contains checks to be run *after* type inference has completed
4successfully. At that point we still need to do occurs checks and ensure that
5`main` has an acceptable type.
7module Type.ExtraChecks (mainType, occurs) where
9import Prelude hiding (maybe)
10import Control.Applicative ((<$>),(<*>))
11import Control.Monad.Error
12import Control.Monad.State
13import qualified Data.Map as Map
14import qualified Data.Traversable as Traverse
15import qualified Data.UnionFind.IO as UF
16import Text.PrettyPrint as P
18import qualified AST.Annotation as A
19import qualified AST.PrettyPrint as PP
20import qualified AST.Type as ST
21import qualified AST.Variable as Var
22import qualified Type.Hint as Hint
23import qualified Type.Type as TT
24import qualified Type.State as TS
29mainType :: TS.Env -> ErrorT [P.Doc] IO (Map.Map String ST.CanonicalType)
31 do environment' <- liftIO $ Traverse.traverse TT.toSrcType environment
32 mainCheck environment'
37 => Map.Map String ST.CanonicalType
38 -> ErrorT [P.Doc] m (Map.Map String ST.CanonicalType)
40 case Map.lookup "main" env of
45 let tipe = ST.deepDealias typeOfMain
47 if tipe `elem` validMainTypes
49 else throwError [ badMainMessage typeOfMain ]
52validMainTypes :: [ST.CanonicalType]
60 fromModule :: [String] -> String -> ST.CanonicalType
61 fromModule home name =
62 ST.Type (Var.fromModule home name)
65 fromModule ["VirtualDom"] "Node"
68 ST.App (fromModule ["Signal"] "Varying") [ tipe ]
72 ST.Type (Var.builtin name)
75 ST.App (fromModule ["Maybe"] "Maybe") [ tipe ]
78 [ ("element", fromModule ["Graphics","Element"] "ElementPrim")
81 [ ("click" , builtin "_Tuple0")
82 , ("color" , maybe (fromModule ["Color"] "Color"))
83 , ("height" , builtin "Int")
84 , ("hover" , builtin "_Tuple0")
85 , ("href" , builtin "String")
86 , ("id" , builtin "Int")
87 , ("opacity", builtin "Float")
88 , ("tag" , builtin "String")
89 , ("width" , builtin "Int")
97badMainMessage :: ST.CanonicalType -> P.Doc
98badMainMessage typeOfMain =
100 [ P.text "Type Error: 'main' must have one of the following types:"
102 , P.text " Element, Html, Varying Element, Varying Html"
104 , P.text "Instead 'main' has type:\n"
105 , P.nest 4 (PP.pretty typeOfMain)
112occurs :: (String, TT.Variable) -> StateT TS.SolverState IO ()
113occurs (name, variable) =
114 do vars <- liftIO $ infiniteVars [] variable
120 do desc <- liftIO $ UF.descriptor var
121 case TT.structure desc of
123 TS.addHint (P.text msg)
126 do liftIO $ UF.setDescriptor var (desc { TT.structure = Nothing })
127 var' <- liftIO $ UF.fresh desc
128 hint <- liftIO $ Hint.create (A.None (P.text name)) (Just msg) var var'
131 msg = "Infinite types are not allowed"
133 infiniteVars :: [TT.Variable] -> TT.Variable -> IO [TT.Variable]
134 infiniteVars seen var =
135 let go = infiniteVars (var:seen) in
139 desc <- UF.descriptor var
140 case TT.structure desc of
145 (++) <$> go a <*> go b
148 (++) <$> go a <*> go b
156 TT.Record1 fields ext ->
157 concat <$> mapM go (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