Line No. | Rev | Author | Line |
---|---|---|---|
1 | 1 | paulosilva | |
2 | {-# LANGUAGE GADTs, FlexibleContexts, MultiParamTypeClasses #-} | ||
3 | {-# OPTIONS_GHC -Wall #-} | ||
4 | |||
5 | ------------------------------------------------------------------------------- | ||
6 | |||
7 | {- | | ||
8 | Module : Language.R.SafeCast | ||
9 | Description : Type safe cast for the expression representation. | ||
10 | Copyright : (c) Paulo Silva | ||
11 | License : LGPL | ||
12 | |||
13 | Maintainer : paufil@di.uminho.pt | ||
14 | Stability : experimental | ||
15 | Portability : portable | ||
16 | |||
17 | -} | ||
18 | |||
19 | ------------------------------------------------------------------------------- | ||
20 | |||
21 | module Language.R.SafeCast ( | ||
22 | rCast | ||
23 | ) where | ||
24 | |||
25 | import Control.GalcError | ||
26 | import Control.Monad.Error | ||
27 | import Data.Equal | ||
28 | import Data.Existential | ||
29 | import Language.R.Syntax | ||
30 | import Language.Type.Constraint | ||
31 | import Language.Type.Equality | ||
32 | import Language.Type.Syntax | ||
33 | |||
34 | ------------------------------------------------------------------------------- | ||
35 | |||
36 | 7 | paulosilva | rCast :: MonadError GalcError m |
37 | 1 | paulosilva | => [Constraint] -> Type t -> R r -> m (R t) |
38 | rCast _ (Rel _ _) BOT = return BOT | ||
39 | rCast _ (Rel _ _) TOP = return TOP | ||
40 | rCast c (Rel t1 t2) (NEG r) = do | ||
41 | r' <- rCast c (Rel t1 t2) r | ||
42 | return $ NEG r' | ||
43 | rCast c (Rel t1 t2) (MEET r1 r2) = do | ||
44 | r1' <- rCast c (Rel t1 t2) r1 | ||
45 | r2' <- rCast c (Rel t1 t2) r2 | ||
46 | return $ MEET r1' r2' | ||
47 | rCast c (Rel t1 t2) (JOIN r1 r2) = do | ||
48 | r1' <- rCast c (Rel t1 t2) r1 | ||
49 | r2' <- rCast c (Rel t1 t2) r2 | ||
50 | return $ JOIN r1' r2' | ||
51 | rCast _ (Rel t1 t2) ID = do | ||
52 | 7 | paulosilva | Eq <- teqE t1 t2 |
53 | 1 | paulosilva | return ID |
54 | rCast c (Rel t1 t2) (CONV r1) = do | ||
55 | r1' <- rCast c (Rel t2 t1) r1 | ||
56 | return $ CONV r1' | ||
57 | rCast c (Rel t1 t2) (COMP t r1 r2) = do | ||
58 | 7 | paulosilva | Hide t' <- typeRewriteE c t |
59 | 1 | paulosilva | r1' <- rCast c (Rel t1 t') r1 |
60 | r2' <- rCast c (Rel t' t2) r2 | ||
61 | return $ COMP t' r1' r2' | ||
62 | rCast c (Rel (Prod t2 t3) t1) (SPLIT r1 r2) = do | ||
63 | r1' <- rCast c (Rel t2 t1) r1 | ||
64 | r2' <- rCast c (Rel t3 t1) r2 | ||
65 | return $ SPLIT r1' r2' | ||
66 | rCast c (Rel t1 t2) (ORD r) = do | ||
67 | 7 | paulosilva | Eq <- teqE t1 t2 |
68 | 1 | paulosilva | r' <- rCast c (Ord t1) r |
69 | return $ ORD r' | ||
70 | rCast c (Rel t2 t1) (FUN f) = do | ||
71 | f' <- rCast c (Fun t2 t1) f | ||
72 | return $ FUN f' | ||
73 | rCast c (Fun t1 t3) (LEFTSEC t2 f s) = do | ||
74 | 7 | paulosilva | Hide t2' <- typeRewriteE c t2 |
75 | 1 | paulosilva | f' <- rCast c (Fun t1 (Prod t2' t3)) f |
76 | s' <- rCast c t2' s | ||
77 | return $ LEFTSEC t2' f' s' | ||
78 | rCast c (Fun t1 t2) (RIGHTSEC t3 f s) = do | ||
79 | 7 | paulosilva | Hide t3' <- typeRewriteE c t3 |
80 | 1 | paulosilva | f' <- rCast c (Fun t1 (Prod t2 t3')) f |
81 | s' <- rCast c t3' s | ||
82 | return $ RIGHTSEC t3' f' s' | ||
83 | rCast c t1 (APPLY t2 f v) = do | ||
84 | 7 | paulosilva | Hide t2' <- typeRewriteE c t2 |
85 | 1 | paulosilva | v' <- rCast c t2' v |
86 | f' <- rCast c (Fun t1 t2') f | ||
87 | return $ APPLY t2' f' v' | ||
88 | rCast c ta (DEF n tb) = do | ||
89 | 7 | paulosilva | Hide tb' <- typeRewriteE c tb |
90 | Eq <- teqE tb' ta | ||
91 | 1 | paulosilva | return $ DEF n ta |
92 | rCast _ _ (Var n) = return (Var n) | ||
93 | rCast c (Rel (Prod t2' t1') (Prod t2 t1)) (PROD r2 r1) = do | ||
94 | r1' <- rCast c (Rel t1' t1) r1 | ||
95 | r2' <- rCast c (Rel t2' t2) r2 | ||
96 | return $ PROD r2' r1' | ||
97 | rCast c (Rel (Either t2' t1') (Either t2 t1)) (EITHER r2 r1) = do | ||
98 | r1' <- rCast c (Rel t1' t1) r1 | ||
99 | r2' <- rCast c (Rel t2' t2) r2 | ||
100 | return $ EITHER r2' r1' | ||
101 | rCast c (Rel (Maybe b) (Maybe a)) (MAYBE r) = do | ||
102 | r' <- rCast c (Rel b a) r | ||
103 | return $ MAYBE r' | ||
104 | rCast c (Rel (List b) (List a)) (LIST r) = do | ||
105 | r' <- rCast c (Rel b a) r | ||
106 | return $ LIST r' | ||
107 | rCast c (Rel (Set b) (Set a)) (SET r) = do | ||
108 | r' <- rCast c (Rel b a) r | ||
109 | return $ SET r' | ||
110 | rCast c (Rel (Map k b) (Map k' a)) (MAP r) = do | ||
111 | 7 | paulosilva | Eq <- teqE k k' |
112 | 1 | paulosilva | r' <- rCast c (Rel b a) r |
113 | return $ MAP r' | ||
114 | 5 | paulosilva | rCast c (Rel (Fun t2 t4) (Fun t1 t3)) (REYNOLDS r2 r1) = do |
115 | r1' <- rCast c (Rel t4 t3) r1 | ||
116 | r2' <- rCast c (Rel t2 t1) r2 | ||
117 | return $ REYNOLDS r2' r1' | ||
118 | 1 | paulosilva | rCast _ (Fun t1 t2) FId = do |
119 | 7 | paulosilva | Eq <- teqE t1 t2 |
120 | 1 | paulosilva | return FId |
121 | rCast c (Fun t1 t3) (FComp t2 f1 f2) = do | ||
122 | 7 | paulosilva | Hide t2' <- typeRewriteE c t2 |
123 | 1 | paulosilva | f1' <- rCast c (Fun t1 t2') f1 |
124 | f2' <- rCast c (Fun t2' t3) f2 | ||
125 | return $ FComp t2' f1' f2' | ||
126 | rCast _ (Ord _) OId = return OId | ||
127 | rCast c (Ord t) (OComp o1 o2) = do | ||
128 | o1' <- rCast c (Ord t) o1 | ||
129 | o2' <- rCast c (Ord t) o2 | ||
130 | return $ OComp o1' o2' | ||
131 | rCast c (Ord t) (OConv o) = do | ||
132 | o' <- rCast c (Ord t) o | ||
133 | return $ OConv o' | ||
134 | rCast c (Ord (Prod a a')) (OProd o) = do | ||
135 | 7 | paulosilva | Eq <- teqE a a' |
136 | 1 | paulosilva | o' <- rCast c (Ord a) o |
137 | return $ OProd o' | ||
138 | rCast c (Fun t1 (Prod t2 t3)) (OJoin o) = do | ||
139 | 7 | paulosilva | Eq <- teqE t1 t2 |
140 | Eq <- teqE t2 t3 | ||
141 | 1 | paulosilva | o' <- rCast c (Ord t1) o |
142 | return $ OJoin o' | ||
143 | rCast c (Fun t1 (Prod t2 t3)) (OMeet o) = do | ||
144 | 7 | paulosilva | Eq <- teqE t1 t2 |
145 | Eq <- teqE t2 t3 | ||
146 | 1 | paulosilva | o' <- rCast c (Ord t1) o |
147 | return $ OMeet o' | ||
148 | rCast c t (OMax o) = do | ||
149 | o' <- rCast c (Ord t) o | ||
150 | return $ OMax o' | ||
151 | rCast c t (OMin o) = do | ||
152 | o' <- rCast c (Ord t) o | ||
153 | return $ OMin o' | ||
154 | rCast c (GC t1 t2) (GDef n f1 f2 o1 o2) = do | ||
155 | f1' <- rCast c (Fun t1 t2) f1 | ||
156 | f2' <- rCast c (Fun t2 t1) f2 | ||
157 | o1' <- rCast c (Ord t1) o1 | ||
158 | o2' <- rCast c (Ord t2) o2 | ||
159 | return $ GDef n f1' f2' o1' o2' | ||
160 | rCast _ (GC t1 t2) GId = do | ||
161 | 7 | paulosilva | Eq <- teqE t1 t2 |
162 | 1 | paulosilva | return $ GId |
163 | rCast c (GC t1 t3) (GComp t2 g1 g2) = do | ||
164 | 7 | paulosilva | Hide t2' <- typeRewriteE c t2 |
165 | 1 | paulosilva | g1' <- rCast c (GC t1 t2') g1 |
166 | g2' <- rCast c (GC t2' t3) g2 | ||
167 | return $ GComp t2' g1' g2' | ||
168 | rCast c (GC t1 t2) (GConv g) = do | ||
169 | g' <- rCast c (GC t2 t1) g | ||
170 | return $ GConv g' | ||
171 | rCast c (Fun t1 t2) (GLAdj g) = do | ||
172 | g' <- rCast c (GC t1 t2) g | ||
173 | return $ GLAdj g' | ||
174 | rCast c (Fun t1 t2) (GUAdj g) = do | ||
175 | g' <- rCast c (GC t2 t1) g | ||
176 | return $ GUAdj g' | ||
177 | rCast c (Ord t1) (GLOrd t2 g) = do | ||
178 | 7 | paulosilva | Hide t2' <- typeRewriteE c t2 |
179 | 1 | paulosilva | g' <- rCast c (GC t1 t2') g |
180 | return $ GLOrd t2' g' | ||
181 | rCast c (Ord t1) (GUOrd t2 g) = do | ||
182 | 7 | paulosilva | Hide t2' <- typeRewriteE c t2 |
183 | 1 | paulosilva | g' <- rCast c (GC t2' t1) g |
184 | return $ GUOrd t2' g' | ||
185 | rCast _ t r = throwError $ CastingError (show r, show t) | ||
186 | |||
187 | ------------------------------------------------------------------------------- |