on master help sign in
Disallow signals-of-signals, functions that involve signals, and signals of functions
bc6ac14Evan Czaplicki
compiler/Type/ExtraChecks.hs+17−10
@@ -49,20 +49,24 @@ portTypes :: Alias.Rules -> E.LExpr -> Either [P.Doc] ()
49portTypes rules expr =
49portTypes rules expr =
50 const () <$> Expr.checkPorts (check In) (check Out) expr
50 const () <$> Expr.checkPorts (check In) (check Out) expr
51 where
51 where
52− check = isValid True
52+ check = isValid False False
53− isValid firstOrder direction name tipe =
53+ isValid seenFunc seenSignal direction name tipe =
54− let valid = isValid firstOrder direction name in
54+ let valid = isValid seenFunc seenSignal direction name in
55 case tipe of
55 case tipe of
56+ T.Data ctor ts
56− T.Data ctor ts | okay ctor -> mapM_ valid ts
57+ | isJs ctor || isElm ctor -> mapM_ valid ts
58+ | ctor == "Signal.Signal" -> handleSignal ts
57− | otherwise -> err "Algebraic Data Types"
59+ | otherwise -> err "Algebraic Data Types"
58
60
59 T.Var _ -> err "free type variables"
61 T.Var _ -> err "free type variables"
60
62
61 T.Lambda _ _ ->
63 T.Lambda _ _ ->
62 case direction of
64 case direction of
63 In -> err "functions"
65 In -> err "functions"
66+ Out | seenFunc -> err "higher-order functions"
67+ | seenSignal -> err "signals that contain functions"
68+ | otherwise ->
64− Out | firstOrder -> mapM_ (isValid False direction name) (T.collectLambdas tipe)
69+ mapM_ (isValid True seenSignal direction name) (T.collectLambdas tipe)
65− | otherwise -> err "higher-order functions"
66
70
67 T.Record _ (Just _) -> err "extended records with free type variables"
71 T.Record _ (Just _) -> err "extended records with free type variables"
68
72
@@ -70,16 +74,19 @@ portTypes rules expr =
70 mapM_ (\(k,v) -> (,) k <$> valid v) fields
74 mapM_ (\(k,v) -> (,) k <$> valid v) fields
71
75
72 where
76 where
73− okay ctor = isJs ctor || isElm ctor
74−
75 isJs ctor =
77 isJs ctor =
76 List.isPrefixOf "JavaScript." ctor
78 List.isPrefixOf "JavaScript." ctor
77 && length (filter (=='.') ctor) == 1
79 && length (filter (=='.') ctor) == 1
78
80
79 isElm ctor =
81 isElm ctor =
80− ctor `elem` ["Int","Float","String","Bool","Maybe.Maybe","_List","Signal.Signal"]
82+ ctor `elem` ["Int","Float","String","Bool","Maybe.Maybe","_List"]
81 || Help.isTuple ctor
83 || Help.isTuple ctor
82
84
85+ handleSignal ts
86+ | seenFunc = err "functions that involve signals"
87+ | seenSignal = err "signals-of-signals"
88+ | otherwise = mapM_ (isValid seenFunc True direction name) ts
89+
83 dir inMsg outMsg = case direction of { In -> inMsg ; Out -> outMsg }
90 dir inMsg outMsg = case direction of { In -> inMsg ; Out -> outMsg }
84 txt = P.text . concat
91 txt = P.text . concat
85
92