2module Types.Alias (dealias, mistakes) where
5import Control.Arrow (second)
6import Data.List (group,sort)
7import qualified Data.Map as Map
8import qualified Data.Set as Set
9import Types.Substitutions (subst)
12builtins :: [(String,([X],Type))]
13builtins = [ ("String", ([], string)) ]
15getAliases :: [Statement] -> Map.Map String ([X],Type)
16getAliases stmts = Map.fromList (builtins ++ concatMap getAlias stmts)
17 where getAlias stmt = case stmt of
18 TypeAlias alias xs t -> [(alias, (xs,t))]
22dealias :: [Statement] -> [Statement]
23dealias stmts = map dealiasS stmts
25 dealiasT :: Type -> Type
28 ADT name ts -> case Map.lookup name (getAliases stmts) of
29 Just (xs,t) -> dealiasT (subst (zip xs ts) t)
30 Nothing -> ADT name (map dealiasT ts)
31 LambdaT t u -> LambdaT (dealiasT t) (dealiasT u)
32 RecordT r t -> RecordT (Map.map (map dealiasT) r) (dealiasT t)
35 dealiasS :: Statement -> Statement
38 Datatype n xs tcs -> Datatype n xs (map (second (map dealiasT)) tcs)
39 ExportEvent js elm tipe -> ExportEvent js elm (dealiasT tipe)
40 ImportEvent js e elm tipe -> ImportEvent js e elm (dealiasT tipe)
41 TypeAnnotation name tipe -> TypeAnnotation name (dealiasT tipe)
42 TypeAlias alias xs tipe -> TypeAlias alias xs (dealiasT tipe)
45mistakes :: [Statement] -> [String]
46mistakes stmts = badKinds stmts ++ dups stmts ++ badOrder stmts
48badKinds :: [Statement] -> [String]
49badKinds stmts = map msg (concatMap badS stmts)
51 msg x = "Type Error: Type alias '" ++ x ++
52 "' was given the wrong number of arguments."
54 badT :: Type -> [String]
58 case Map.lookup name (getAliases stmts) of
59 Just (xs,t) | length xs == length ts -> []
61 Nothing -> concatMap badT ts
62 LambdaT t u -> badT t ++ badT u
63 RecordT r t -> badT t ++ concatMap badT (concat (Map.elems r))
66 badS :: Statement -> [String]
69 Datatype _ _ tcs -> concatMap badT (concatMap snd tcs)
70 ExportEvent _ _ tipe -> badT tipe
71 ImportEvent _ _ _ tipe -> badT tipe
72 TypeAnnotation _ tipe -> badT tipe
73 TypeAlias _ _ tipe -> badT tipe
76annotation :: Statement -> [String]
79 TypeAnnotation name _ -> [name]
82definition :: Statement -> [String]
85 Definition d -> [defName d]
88defName :: Def -> String
94dups :: [Statement] -> [String]
95dups stmts = map defMsg (dup definition) ++ map annMsg (dup annotation)
97 dup :: (Statement -> [String]) -> [String]
98 dup f = map head . filter ((>1) . length) . group . sort $ concatMap f stmts
100 msg = "Syntax Error: There can only be one "
101 defMsg x = msg ++ "top-level definition of '" ++ x ++ "'."
102 annMsg x = msg ++ "type annotation for '" ++ x ++ "'."
104badOrder :: [Statement] -> [String]
105badOrder stmts = map msg $ missings (sort $ expectedPairs as ds) (sort $ actualPairs stmts)
107 msg x = "Syntax Error: The type annotation for '" ++ x ++
108 "' must be directly above its definition."
109 as = sort $ concatMap annotation stmts
110 ds = sort $ concatMap definition stmts
112 expectedPairs :: [String] -> [String] -> [String]
113 expectedPairs as ds =
115 (x:xs, y:ys) -> case compare x y of
116 LT -> expectedPairs xs (y:ys)
117 EQ -> x : expectedPairs xs ys
118 GT -> expectedPairs (x:xs) ys
121 actualPairs :: [Statement] -> [String]
124 TypeAnnotation n _ : Definition d : rest ->
125 (if n == defName d then [n] else []) ++ actualPairs rest
126 t:s:rest -> actualPairs (s:rest)
129 missings :: [String] -> [String] -> [String]
130 missings expected actual =
131 case (expected, actual) of
132 (e:es, a:as) -> case compare e a of
133 LT -> e : missings es (a:as)
135 GT -> a : missings (e:es) as
137 ( _ , [] ) -> expected
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