@@ -1,207 +0,0 @@
1−module Transform.Canonicalize.Wire (checkForeignInput, checkForeignOutput, input) where
3−import Control.Applicative ((<$>))
4−import Control.Monad.Error (forM_, throwError)
5−import Text.PrettyPrint as P
7−import qualified AST.Declaration as D
8−import qualified AST.Expression.Canonical as Canonical
9−import qualified AST.PrettyPrint as PP
10−import qualified AST.Type as ST
11−import qualified AST.Variable as Var
12−import qualified Transform.Canonicalize.Environment as Env
15−throw :: [Doc] -> Env.Canonicalizer [P.Doc] a
17− throwError [ P.vcat err ]
20−checkForeignInput :: String -> ST.CanonicalType -> Env.Canonicalizer [P.Doc] ()
21−checkForeignInput name tipe =
22− checkForeign In name tipe tipe
25−checkForeignOutput :: String -> ST.CanonicalType -> Env.Canonicalizer [P.Doc] ()
26−checkForeignOutput name tipe =
27− checkForeign Out name tipe tipe
30−data Direction = In | Out
38− -> Env.Canonicalizer [P.Doc] ()
39−checkForeign direction name rootType tipe =
41− ST.Aliased _ args t ->
42− checkForeign direction name rootType (ST.dealias args t)
44− ST.App (ST.Type signal) [t]
45− | Var.isStream signal ->
46− validForeignType False (Just Stream) direction name rootType t
48− | Var.isVarying signal ->
49− validForeignType False (Just Varying) direction name rootType t
52− validForeignType False Nothing direction name rootType tipe
55−data Signal = Stream | Varying
65− -> Env.Canonicalizer [P.Doc] ()
66−validForeignType seenFunc seenSignal direction name rootType tipe =
67− let valid localType =
68− validForeignType seenFunc seenSignal direction name rootType localType
71− throw (foreignError name direction rootType tipe kind)
74− ST.Aliased _ args t ->
75− valid (ST.dealias args t)
78− case any ($ v) [ Var.isJson, Var.isPrimitive, Var.isTuple ] of
80− False -> err "It contains an unsupported type"
85− ST.App (ST.Type v) [t]
86− | Var.isMaybe v -> valid t
87− | Var.isArray v -> valid t
88− | Var.isList v -> valid t
90− ST.App (ST.Type v) ts
91− | Var.isTuple v -> mapM_ valid ts
94− err "It contains an unsupported type"
97− err "It contains a free type variable"
101− In -> err "It contains functions"
104− then err "It contains higher-order functions"
108− err "It is a streams that contains a function"
111− err "It is a varying value that contains a function"
114− forM_ (ST.collectLambdas tipe)
115− (validForeignType True seenSignal direction name rootType)
117− ST.Record _ (Just _) ->
118− err "It contains extended records with free type variables"
120− ST.Record fields Nothing ->
121− mapM_ (\(k,v) -> (,) k <$> valid v) fields
131−foreignError name direction rootType localType problemMessage =
132− [ P.text ("Foreign " ++ dir "Input" "Output" ++ " Error:")
135− [ txt [ "The foreign ", wire, " named '", name, "' has an invalid type.\n" ]
136− , P.nest 4 (PP.pretty rootType) <> P.text "\n"
137− , txt [ problemMessage, ":\n" ]
138− , P.nest 4 (PP.pretty localType) <> P.text "\n"
139− , txt [ "Acceptable values for foreign ", wire, "s include:" ]
140− , txt [ " Ints, Floats, Bools, Strings, Maybes, Lists, Arrays, Tuples, unit values," ]
141− , txt [ " Json.Values, ", dir "" "first-order functions, tasks, ", "and concrete records." ]
150− txt = P.text . concat
153− dir "input" "output"
158− -> Maybe Canonical.Expr
160− -> Env.Canonicalizer [P.Doc] D.CanonicalLoopback
161−input name maybeExpr tipe =
164− case ST.deepDealias tipe of
166− [ ("address", ST.App (ST.Type address) [a])
167− , ("stream", ST.App (ST.Type stream) [b])
170− | Var.isStream stream && Var.isAddress address && a == b ->
171− return (D.Address name tipe)
175− throw $ inputError name tipe $
176− [ P.text "An input like this must be a Stream.Input" ]
179− case ST.deepDealias tipe of
180− ST.App (ST.Type signal) [ ST.App (ST.Type result) [failure,success] ]
181− | Var.isStream signal && Var.isResult result ->
183− Var.fromModule ["Task"] "Task"
185− ST.App (ST.Type signal) [ ST.App (ST.Type task) [failure,success] ]
187− return (D.Task name taskType expr tipe)
190− throw $ inputError name tipe $
191− [ P.text "An input that runs tasks must be a stream of results."
192− , P.text "Something like the following:\n"
193− , P.text " Stream (Result Http.Error String)"
194− , P.text " Stream (Result x ())"
198−inputError :: String -> ST.CanonicalType -> [Doc] -> [Doc]
199−inputError name tipe message =
200− [ P.text "Input Error:"
203− [ P.text ("The input named '" ++ name ++ "' has an invalid type.\n")
204− , P.nest 4 (PP.pretty tipe) <> P.text "\n"