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 (effectTypes, 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
29effectTypes :: TS.Env -> ErrorT [P.Doc] IO (Map.Map String ST.CanonicalType)
30effectTypes environment =
31 do environment' <- liftIO $ Traverse.traverse TT.toSrcType environment
32 mainCheck environment'
40 => Map.Map String ST.CanonicalType
41 -> ErrorT [P.Doc] m ()
43 case Map.lookup "main" env of
48 let tipe = ST.deepDealias typeOfMain
50 if tipe `elem` validMainTypes
52 else throwError [ badMainMessage typeOfMain ]
55validMainTypes :: [ST.CanonicalType]
63 fromModule :: [String] -> String -> ST.CanonicalType
64 fromModule home name =
65 ST.Type (Var.fromModule home name)
68 fromModule ["VirtualDom"] "Node"
71 ST.App (fromModule ["SignalTypes"] "Signal") [ tipe ]
75 ST.Type (Var.builtin name)
78 ST.App (fromModule ["Maybe"] "Maybe") [ tipe ]
81 [ ("element", fromModule ["Graphics","Element"] "ElementPrim")
84 [ ("click" , builtin "_Tuple0")
85 , ("color" , maybe (fromModule ["Color"] "Color"))
86 , ("height" , builtin "Int")
87 , ("hover" , builtin "_Tuple0")
88 , ("href" , builtin "String")
89 , ("id" , builtin "Int")
90 , ("opacity", builtin "Float")
91 , ("tag" , builtin "String")
92 , ("width" , builtin "Int")
100badMainMessage :: ST.CanonicalType -> P.Doc
101badMainMessage typeOfMain =
103 [ P.text "Type Error: 'main' must have one of the following types:"
105 , P.text " Element, Html, Signal Element, Signal Html"
107 , P.text "Instead 'main' has type:\n"
108 , P.nest 4 (PP.pretty typeOfMain)
115occurs :: (String, TT.Variable) -> StateT TS.SolverState IO ()
116occurs (name, variable) =
117 do vars <- liftIO $ infiniteVars [] variable
123 do desc <- liftIO $ UF.descriptor var
124 case TT.structure desc of
126 TS.addHint (P.text msg)
129 do liftIO $ UF.setDescriptor var (desc { TT.structure = Nothing })
130 var' <- liftIO $ UF.fresh desc
131 hint <- liftIO $ Hint.create (A.None (P.text name)) (Just msg) var var'
134 msg = "Infinite types are not allowed"
136 infiniteVars :: [TT.Variable] -> TT.Variable -> IO [TT.Variable]
137 infiniteVars seen var =
138 let go = infiniteVars (var:seen) in
142 desc <- UF.descriptor var
143 case TT.structure desc of
148 (++) <$> go a <*> go b
151 (++) <$> go a <*> go b
159 TT.Record1 fields ext ->
160 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