Skip to content

Commit 09c4314

Browse files
committed
Merge pull request purescript#1614 from purescript/1335
Fix purescript#1335, track scoped type variables when skolemizing
2 parents 3901ae7 + 79e7a09 commit 09c4314

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

examples/passing/1335.purs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module Main where
2+
3+
import Prelude
4+
import Control.Monad.Eff.Console (log)
5+
6+
x :: forall a. a -> String
7+
x a = y "Done"
8+
where
9+
y :: forall a. (Show a) => a -> String
10+
y a = show (a :: a)
11+
12+
main = log (x 0)

src/Language/PureScript/TypeChecker/Skolems.hs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import Prelude.Compat
2929

3030
import Data.List (nub, (\\))
3131
import Data.Monoid
32+
import Data.Functor.Identity (Identity(), runIdentity)
3233

3334
import Control.Monad.Error.Class (MonadError(..))
3435
import Control.Monad.State.Class (MonadState(..), gets, modify)
@@ -38,6 +39,7 @@ import Language.PureScript.AST
3839
import Language.PureScript.Errors
3940
import Language.PureScript.TypeChecker.Monad
4041
import Language.PureScript.Types
42+
import Language.PureScript.Traversals (defS)
4143

4244
-- |
4345
-- Generate a new skolem constant
@@ -78,16 +80,26 @@ skolemize ident sko scope = replaceTypeVars ident (Skolem ident sko scope)
7880
-- only example of scoped type variables.
7981
--
8082
skolemizeTypesInValue :: String -> Int -> SkolemScope -> Expr -> Expr
81-
skolemizeTypesInValue ident sko scope = let (_, f, _) = everywhereOnValues id onExpr onBinder in f
83+
skolemizeTypesInValue ident sko scope =
84+
let
85+
(_, f, _, _, _) = everywhereWithContextOnValuesM [] defS onExpr onBinder defS defS
86+
in runIdentity . f
8287
where
83-
onExpr :: Expr -> Expr
84-
onExpr (SuperClassDictionary c ts) = SuperClassDictionary c (map (skolemize ident sko scope) ts)
85-
onExpr (TypedValue check val ty) = TypedValue check val (skolemize ident sko scope ty)
86-
onExpr other = other
88+
onExpr :: [String] -> Expr -> Identity ([String], Expr)
89+
onExpr sco (SuperClassDictionary c ts)
90+
| ident `notElem` sco = return (sco, SuperClassDictionary c (map (skolemize ident sko scope) ts))
91+
onExpr sco (TypedValue check val ty)
92+
| ident `notElem` sco = return (sco ++ peelTypeVars ty, TypedValue check val (skolemize ident sko scope ty))
93+
onExpr sco other = return (sco, other)
8794

88-
onBinder :: Binder -> Binder
89-
onBinder (TypedBinder ty b) = TypedBinder (skolemize ident sko scope ty) b
90-
onBinder other = other
95+
onBinder :: [String] -> Binder -> Identity ([String], Binder)
96+
onBinder sco (TypedBinder ty b)
97+
| ident `notElem` sco = return (sco ++ peelTypeVars ty, TypedBinder (skolemize ident sko scope ty) b)
98+
onBinder sco other = return (sco, other)
99+
100+
peelTypeVars :: Type -> [String]
101+
peelTypeVars (ForAll i ty _) = i : peelTypeVars ty
102+
peelTypeVars _ = []
91103

92104
-- |
93105
-- Ensure skolem variables do not escape their scope

0 commit comments

Comments
 (0)