1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Canonicalize.Effects
10import qualified Data.Foldable as F
11import Data.Text (Text)
13import qualified AST.Effects as Effects
14import qualified AST.Type as T
15import qualified AST.Variable as Var
16import qualified Reporting.Annotation as A
17import qualified Reporting.Error.Canonicalize as Error
18import qualified Reporting.Region as R
19import qualified Reporting.Result as Result
20import qualified Canonicalize.Environment as Env
21import qualified Canonicalize.Type as Canonicalize
22import Canonicalize.Variable (Result)
29toExposedValues :: Effects.Raw -> [Text]
30toExposedValues effects =
35 Effects.Manager _ _ ->
39 map (Effects._rawName . A.drop) ports
46canonicalize :: Env.Env -> Effects.Raw -> Result Effects.Canonical
47canonicalize env effects =
50 Result.ok Effects.None
52 Effects.Manager _ info ->
53 Result.ok (Effects.Manager (Env.getPackage env) info)
55 Effects.Port rawPorts ->
56 Effects.Port <$> traverse (canonicalizeRawPort env) rawPorts
61 -> A.Commented Effects.PortRaw
62 -> Result (A.Commented Effects.PortCanonical)
63canonicalizeRawPort env (A.A ann (Effects.PortRaw name rawType)) =
64 do tipe <- Canonicalize.tipe env rawType
65 kind <- figureOutKind (fst ann) name tipe
66 Result.ok (A.A ann (Effects.PortCanonical name kind tipe))
69figureOutKind :: R.Region -> Text -> T.Canonical -> Result Effects.Kind
70figureOutKind region name rootType =
71 case T.deepDealias rootType of
72 T.Lambda outgoingType (T.App (T.Type effect) [T.Var _])
73 | effect == Var.cmd ->
74 pure (Effects.Outgoing outgoingType)
75 <* checkPortType (makeError region name) outgoingType
77 T.Lambda (T.Lambda incomingType (T.Var msg1)) (T.App (T.Type effect) [T.Var msg2])
78 | effect == Var.sub && msg1 == msg2 ->
79 pure (Effects.Incoming incomingType)
80 <* checkPortType (makeError region name) incomingType
83 Result.throw region (Error.BadPort name rootType)
86makeError :: R.Region -> Text -> T.Canonical -> Maybe Text -> A.Located Error.Error
87makeError region name tipe maybeMessage =
88 A.A region (Error.port name tipe maybeMessage)
92-- CHECK INCOMING AND OUTGOING TYPES
97 => (T.Canonical -> Maybe Text -> A.Located e)
99 -> Result.Result i w e ()
100checkPortType mkError tipe =
103 checkPortType mkError
106 Result.throwMany [mkError tipe maybeMsg]
109 T.Aliased _ args aliasedType ->
110 check (T.dealias args aliasedType)
113 if Var.isJson name || Var.isPrimitive name || Var.isTuple name then
122 T.App (T.Type name) [arg]
123 | Var.isMaybe name -> check arg
124 | Var.isArray name -> check arg
125 | Var.isList name -> check arg
127 T.App (T.Type name) args
128 | Var.isTuple name ->
129 F.traverse_ check args
135 throw (Just "free type variable")
138 throw (Just "function")
140 T.Record _ (Just _) ->
141 throw (Just "extended record")
143 T.Record fields Nothing ->
144 F.traverse_ (\(k,v) -> (,) k <$> check v) 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