Skip to content

Commit fe0aa0d

Browse files
authored
Fix proxies: synonyms, inference, traversals, instances (purescript#3095)
1 parent 2bce858 commit fe0aa0d

File tree

7 files changed

+73
-2
lines changed

7 files changed

+73
-2
lines changed

examples/passing/Proxy.purs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,63 @@ i = @"foo"
1818
j :: Unit
1919
j = h i
2020

21+
data P t = P
22+
23+
switchP :: forall p. @p -> P p
24+
switchP _ = P :: P p
25+
26+
switchP' :: forall p. P p -> @p
27+
switchP' P = @p
28+
29+
type Ap f x = f x
30+
infix 4 type Ap as $
31+
type Eg0 = Array $ Unit
32+
type Eg1 = Array $ Unit
33+
34+
eg0 :: P Eg0
35+
eg0 = switchP @Eg1
36+
37+
eg0' :: @Eg0
38+
eg0' = switchP' (P :: P Eg1)
39+
40+
eg1 :: @Eg0
41+
eg1 = switchP' (switchP @Eg1)
42+
43+
eg1' :: P Eg0
44+
eg1' = switchP (switchP' (P :: P Eg0))
45+
46+
47+
class Go a b | a -> b
48+
49+
instance goInst :: Go Int Int
50+
51+
goGo :: forall a b c. Go a b => Go b c => @a -> P c
52+
goGo _ = P :: P c
53+
54+
go0 :: P Int
55+
go0 = goGo @Int
56+
57+
type Go1 = Int
58+
type Go1' = Int
59+
60+
go1 :: P Go1
61+
go1 = goGo @Go1'
62+
63+
64+
class Determined a p | a -> p where
65+
determined :: a -> p
66+
67+
instance determinedIntProxy :: Determined Int @Int where
68+
determined _ = @Int
69+
70+
instance determinedProxyInt :: Determined @Int Int where
71+
determined _ = 42
72+
73+
determined0 :: @Int
74+
determined0 = determined 42
75+
76+
determined1 :: Int
77+
determined1 = determined @Int
78+
79+
2180
main = log "Done"

src/Language/PureScript/AST/Traversals.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,7 @@ accumTypes f = everythingOnValues mappend forDecls forValues (const mempty) (con
635635
forValues (TypeClassDictionary c _ _) = mconcat (fmap f (constraintArgs c))
636636
forValues (DeferredDictionary _ tys) = mconcat (fmap f tys)
637637
forValues (TypedValue _ _ ty) = f ty
638+
forValues (Proxy ty) = f ty
638639
forValues _ = mempty
639640

640641
accumKinds
@@ -668,6 +669,7 @@ accumKinds f = everythingOnValues mappend forDecls forValues (const mempty) (con
668669
forValues (TypeClassDictionary c _ _) = foldMap forTypes (constraintArgs c)
669670
forValues (DeferredDictionary _ tys) = foldMap forTypes tys
670671
forValues (TypedValue _ _ ty) = forTypes ty
672+
forValues (Proxy ty) = forTypes ty
671673
forValues _ = mempty
672674

673675
forTypes (KindedType _ k) = f k
@@ -681,5 +683,6 @@ overTypes f = let (_, f', _) = everywhereOnValues id g id in f'
681683
where
682684
g :: Expr -> Expr
683685
g (TypedValue checkTy val t) = TypedValue checkTy val (f t)
686+
g (Proxy t) = Proxy (f t)
684687
g (TypeClassDictionary c sco hints) = TypeClassDictionary (mapConstraintArgs (fmap f) c) sco hints
685688
g other = other

src/Language/PureScript/Sugar/Names.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ renameInModule imports (Module modSS coms mn decls exps) =
269269
(,) s <$> (Constructor <$> updateDataConstructorName name pos)
270270
updateValue s@(pos, _) (TypedValue check val ty) =
271271
(,) s <$> (TypedValue check val <$> updateTypesEverywhere pos ty)
272+
updateValue s@(pos, _) (Proxy ty) =
273+
(,) s <$> (Proxy <$> updateTypesEverywhere pos ty)
272274
updateValue s v = return (s, v)
273275

274276
updateBinder

src/Language/PureScript/Sugar/Operators.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,9 @@ updateTypes goType = (goDecl, goExpr, goBinder)
356356
goExpr pos (TypedValue check v ty) = do
357357
ty' <- goType' pos ty
358358
return (pos, TypedValue check v ty')
359+
goExpr pos (Proxy ty) = do
360+
ty' <- goType' pos ty
361+
return (pos, Proxy ty')
359362
goExpr pos other = return (pos, other)
360363

361364
goBinder :: Maybe SourceSpan -> Binder -> m (Maybe SourceSpan, Binder)

src/Language/PureScript/TypeChecker.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ checkTypeClassInstance cls i = check where
199199
TypeApp t1 t2 -> check t1 >> check t2
200200
REmpty | isFunDepDetermined -> return ()
201201
RCons _ hd tl | isFunDepDetermined -> check hd >> check tl
202+
ProxyType ty -> check ty
202203
ty -> throwError . errorMessage $ InvalidInstanceHead ty
203204

204205
-- |

src/Language/PureScript/TypeChecker/Entailment.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,7 @@ matches deps TypeClassDictionaryInScope{..} tys =
496496
typeHeadsAreEqual t (TypeVar v) = (Match (), M.singleton v [t])
497497
typeHeadsAreEqual (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = (Match (), M.empty)
498498
typeHeadsAreEqual (TypeLevelString s1) (TypeLevelString s2) | s1 == s2 = (Match (), M.empty)
499+
typeHeadsAreEqual (ProxyType t1) (ProxyType t2) = typeHeadsAreEqual t1 t2
499500
typeHeadsAreEqual (TypeApp h1 t1) (TypeApp h2 t2) =
500501
both (typeHeadsAreEqual h1 h2) (typeHeadsAreEqual t1 t2)
501502
typeHeadsAreEqual REmpty REmpty = (Match (), M.empty)
@@ -538,6 +539,7 @@ matches deps TypeClassDictionaryInScope{..} tys =
538539
typesAreEqual (TypeLevelString s1) (TypeLevelString s2) = s1 == s2
539540
typesAreEqual (TypeConstructor c1) (TypeConstructor c2) = c1 == c2
540541
typesAreEqual (TypeApp h1 t1) (TypeApp h2 t2) = typesAreEqual h1 h2 && typesAreEqual t1 t2
542+
typesAreEqual (ProxyType t1) (ProxyType t2) = typesAreEqual t1 t2
541543
typesAreEqual REmpty REmpty = True
542544
typesAreEqual r1 r2 | isRCons r1 || isRCons r2 =
543545
let (common, rest) = alignRowsWith typesAreEqual r1 r2

src/Language/PureScript/TypeChecker/Types.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,9 @@ infer' (IfThenElse cond th el) = do
394394
infer' (Let ds val) = do
395395
(ds', val'@(TypedValue _ _ valTy)) <- inferLetBinding [] ds val infer
396396
return $ TypedValue True (Let ds' val') valTy
397-
infer' (Proxy ty) =
398-
return $ TypedValue True (Proxy ty) (ProxyType ty)
397+
infer' (Proxy ty) = do
398+
ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
399+
return $ TypedValue True (Proxy ty') (ProxyType ty')
399400
infer' (DeferredDictionary className tys) = do
400401
dicts <- getTypeClassDictionaries
401402
hints <- getHints

0 commit comments

Comments
 (0)