@@ -39,6 +39,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
39
39
40
40
module Language.CQL.Typeside where
41
41
import Control.DeepSeq
42
+ import Data.Bifunctor (first )
42
43
import Data.List (nub )
43
44
import Data.Map.Strict hiding (foldr )
44
45
import qualified Data.Map.Strict as Map
@@ -88,13 +89,15 @@ typecheckTypeside = typeOfCol . tsToCol
88
89
89
90
-- | Converts a typeside to a collage.
90
91
tsToCol :: (Ord var , Ord ty , Ord sym ) => Typeside var ty sym -> Collage var ty sym Void Void Void Void Void
91
- tsToCol (Typeside t s e _) = Collage e' t Set. empty s Map. empty Map. empty Map. empty Map. empty
92
- where e' = Set. map (\ (g,x)-> (Map. map Left g, x)) e
92
+ tsToCol (Typeside tys syms eqs _) =
93
+ Collage (leftify eqs) tys Set. empty syms mempty mempty mempty mempty
94
+ where
95
+ leftify = Set. map (first (fmap Left ))
93
96
94
97
data TypesideEx :: * where
95
98
TypesideEx
96
- :: forall var ty sym . (MultiTyMap '[Show , Ord , Typeable , NFData ] '[var , ty , sym ]) =>
97
- Typeside var ty sym
99
+ :: forall var ty sym . (MultiTyMap '[Show , Ord , Typeable , NFData ] '[var , ty , sym ])
100
+ => Typeside var ty sym
98
101
-> TypesideEx
99
102
100
103
instance NFData TypesideEx where
@@ -119,42 +122,50 @@ data TypesideRaw' = TypesideRaw'
119
122
, tsraw_imports :: [TypesideExp ]
120
123
} deriving (Eq , Show )
121
124
125
+
122
126
evalTypesideRaw :: Options -> TypesideRaw' -> [TypesideEx ] -> Err TypesideEx
123
- evalTypesideRaw ops t a' = do
124
- a <- doImports a'
125
- r <- evalTypesideRaw' t a
126
- l <- toOptions ops $ tsraw_options t
127
- p <- createProver (tsToCol r) l
128
- pure $ TypesideEx $ Typeside (tys r) (syms r) (eqs r) (f p)
127
+ evalTypesideRaw opts tsRaw imports = do
128
+ imports' <- doImports imports
129
+ ts <- evalTypesideRaw' tsRaw imports'
130
+ opts' <- toOptions opts $ tsraw_options tsRaw
131
+ prover <- createProver (tsToCol ts) opts'
132
+ let eq = \ ctx -> prove prover (Map. map Left ctx)
133
+ pure $ TypesideEx $ Typeside (tys ts) (syms ts) (eqs ts) eq
129
134
where
130
- f p ctx = prove p (Map. map Left ctx)
131
135
doImports :: forall var ty sym . (Typeable var , Typeable ty , Typeable sym ) => [TypesideEx ] -> Err [Typeside var ty sym ]
132
- doImports [] = return []
133
- doImports (TypesideEx ts : r) = case cast ts of
134
- Nothing -> Left " Bad import"
135
- Just ts' -> do { r' <- doImports r ; return $ ts' : r' }
136
-
137
- evalTypesideRaw' :: TypesideRaw' -> [Typeside Var Ty Sym ] -> Err (Typeside Var Ty Sym )
138
- evalTypesideRaw' (TypesideRaw' ttys tsyms teqs _ _) is = do
139
- tys' <- fromList'' ttys
140
- syms' <- toMapSafely tsyms
136
+ doImports [] = return []
137
+ doImports (TypesideEx imp: imps) = do
138
+ imp' <- note " Bad import" $ cast imp
139
+ imps' <- doImports imps
140
+ return $ imp' : imps'
141
+
142
+ evalTypesideRaw' :: TypesideRaw' -> [Typeside Var Ty Sym ] -> Err (Typeside Var Ty Sym )
143
+ evalTypesideRaw' (TypesideRaw' ttys tsyms teqs _ _) importedTys = do
144
+ tys' <- toSetSafely ttys
145
+ syms' <- toMapSafely tsyms
141
146
eqs' <- evalEqs (addImportedSyms syms') teqs
142
- return $ Typeside (Set. union imported_tys ' tys') (addImportedSyms syms') (Set. union imported_eqs eqs') undefined -- leave prover blank
147
+ return $ Typeside (Set. union importedTys ' tys') (addImportedSyms syms') (Set. union importedEqs eqs') prover
143
148
where
144
- imported_tys' = foldr Set. union Set. empty $ fmap tys is
145
- addImportedSyms syms' = foldr (\ (f',(s,t)) m -> Map. insert f' (s,t) m) syms' $ concatMap (Map. toList . syms) is
146
- imported_eqs = foldr Set. union Set. empty $ fmap eqs is
149
+ prover = undefined -- intentionally left blank; is there a less explosive way to do this?
150
+ importedTys' = foldMap tys importedTys
151
+ importedEqs = foldMap eqs importedTys
152
+ addImportedSyms syms' = foldr (\ (f',(s,t)) m -> Map. insert f' (s,t) m) syms' $ concatMap (Map. toList . syms) importedTys
153
+
147
154
evalEqs _ [] = pure Set. empty
148
155
evalEqs syms' ((ctx, lhs, rhs): eqs') = do
149
- ctx' <- check syms' ctx lhs rhs
156
+ ctx' <- check syms' ctx lhs rhs
150
157
lhs' <- evalTerm syms' ctx' lhs
151
158
rhs' <- evalTerm syms' ctx' rhs
152
- rest <- evalEqs syms' eqs'
159
+ rest <- evalEqs syms' eqs'
153
160
pure $ Set. insert (ctx', EQ (lhs', rhs')) rest
154
- evalTerm _ ctx (RawApp v [] ) | Map. member v ctx = pure $ Var v
155
- evalTerm syms' ctx (RawApp v l) = do { l' <- mapM (evalTerm syms' ctx) l ; pure $ Sym v l' }
161
+
162
+ evalTerm :: Monad m => t -> Ctx String a -> RawTerm -> m (Term String ty String en fk att gen sk )
163
+ evalTerm _ ctx (RawApp v [] ) | Map. member v ctx = pure $ Var v
164
+ evalTerm syms' ctx (RawApp v l) = Sym v <$> mapM (evalTerm syms' ctx) l
165
+
156
166
check _ [] _ _ = pure Map. empty
157
167
check syms' ((v,t): l) lhs rhs = do {x <- check syms' l lhs rhs; t' <- infer v t syms' lhs rhs; pure $ Map. insert v t' x}
168
+
158
169
infer _ (Just t) _ _ _ = return t
159
170
infer v _ syms' lhs rhs = case (t1s, t2s) of
160
171
([t1] , [t2] ) -> if t1 == t2 then return t1 else Left $ " Type mismatch on " ++ show v ++ " in " ++ show lhs ++ " = " ++ show rhs ++ " , types are " ++ show t1 ++ " and " ++ show t2
@@ -166,6 +177,7 @@ evalTypesideRaw' (TypesideRaw' ttys tsyms teqs _ _) is = do
166
177
where
167
178
t1s = nub $ typesOf v syms' lhs
168
179
t2s = nub $ typesOf v syms' rhs
180
+
169
181
typesOf _ _ (RawApp _ [] ) = []
170
182
typesOf v syms' (RawApp f' as) = concatMap fn $ zip as $ maybe [] fst $ Map. lookup f' syms'
171
183
where
@@ -195,17 +207,18 @@ sqlTypeNames =
195
207
, " Real"
196
208
, " Smallint" , " String"
197
209
, " Text" , " Time" , " Timestamp" , " Tinyint"
198
- , " Varbinary" , " Varchar" ]
210
+ , " Varbinary" , " Varchar"
211
+ ]
199
212
200
213
-----------------------------------------------------------------------------------------------------------
201
214
-- Expression syntax
202
215
203
- -- there are practical haskell type system related reasons to not want this to be a gadt
216
+ -- There are practical haskell type system related reasons to not want this to be a GADT.
204
217
data TypesideExp where
205
- TypesideVar :: String -> TypesideExp
206
- TypesideInitial :: TypesideExp
207
- TypesideRaw :: TypesideRaw' -> TypesideExp
208
- TypesideSql :: TypesideExp
218
+ TypesideVar :: String -> TypesideExp
219
+ TypesideInitial :: TypesideExp
220
+ TypesideRaw :: TypesideRaw' -> TypesideExp
221
+ TypesideSql :: TypesideExp
209
222
210
223
deriving instance Eq TypesideExp
211
224
deriving instance Show TypesideExp
@@ -217,7 +230,6 @@ instance Deps TypesideExp where
217
230
TypesideSql -> []
218
231
TypesideRaw (TypesideRaw' _ _ _ _ i) -> concatMap deps i
219
232
220
-
221
233
getOptionsTypeside :: TypesideExp -> [(String , String )]
222
234
getOptionsTypeside x = case x of
223
235
TypesideSql -> []
0 commit comments