git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge pull request #1614 from purescript/1335

Fix #1335, track scoped type variables when skolemizing

commit09c43143bfac552bf100847cad4bb43519ed0cae authorPhil Freeman <paf31@cantab.net> dateSat 7 Nov 2015, 17:43 (11 years ago) parent3901ae779e7a09
2 files changed+32−8
examples/passing/1335.purs+12 src/Language/PureScript/TypeChecker/Skolems.hs+20−8
examples/passing/1335.pursnew file+12
@@ -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+20−8
@@ -29,6 +29,7 @@ import Prelude.Compat
2929
3030import Data.List (nub, (\\))
3131import Data.Monoid
32+import Data.Functor.Identity (Identity(), runIdentity)
3233
3334import Control.Monad.Error.Class (MonadError(..))
3435import Control.Monad.State.Class (MonadState(..), gets, modify)
@@ -38,6 +39,7 @@ import Language.PureScript.AST
3839import Language.PureScript.Errors
3940import Language.PureScript.TypeChecker.Monad
4041import 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--
8082skolemizeTypesInValue :: 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