git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Prevent skolem variables from escaping
commitce885eff9a3a641668d44d1285a14690b5bec85d authorPhil Freeman <paf31@cantab.net> dateWed 27 Nov 2013, 16:46 (13 years ago) parentd6a694d
2 files changed+18−2
examples/failing/SkolemEscape.ps+3 src/Language/PureScript/TypeChecker/Types.hs+15−2
examples/failing/SkolemEscape.psnew file+3
@@ -0,0 +1,3 @@
1+foreign import foo :: (forall a. a -> a) -> Number
2+
3+test = \x -> foo x
src/Language/PureScript/TypeChecker/Types.hs+15−2
@@ -22,7 +22,9 @@ import Data.List
2222import Data.Maybe (isJust, fromMaybe)
2323import Data.Function
2424import qualified Data.Data as D
25−import Data.Generics (everywhere, everywhereM, everything, everywhereBut, mkT, mkM, mkQ, extM, extQ)
25+import Data.Generics
26+ (something, everywhere, everywhereM, everything, everywhereBut,
27+ mkT, mkM, mkQ, extM, extQ)
2628
2729import Language.PureScript.Values
2830import Language.PureScript.Types
@@ -145,7 +147,6 @@ isFunction (Abs _ _) = True
145147isFunction (TypedValue untyped _) = isFunction untyped
146148isFunction _ = False
147149
148−-- TODO: check skolems don't escape
149150typeOf :: Maybe Ident -> Value -> Check Type
150151typeOf name val = do
151152 (ty, sub, checks) <- runSubst $ case name of
@@ -164,6 +165,7 @@ typeOf name val = do
164165 return ty
165166 _ -> infer M.empty val
166167 escapeCheck checks ty sub
168+ skolemEscapeCheck ty
167169 return $ varIfUnknown $ desaturateAllTypeSynonyms $ setifyAll ty
168170
169171escapeCheck :: [AnyUnifiable] -> Type -> Substitution -> Check ()
@@ -176,6 +178,17 @@ escapeCheck checks ty sub =
176178 let unsolvedUnknowns = nub . unknowns $ apply sub t
177179 guardWith "Escape check fails" $ null $ unsolvedUnknowns \\ visibleUnknowns
178180
181+skolemEscapeCheck :: Type -> Check ()
182+skolemEscapeCheck ty =
183+ case something (extQ (mkQ Nothing findSkolems) findRSkolems) ty of
184+ Nothing -> return ()
185+ Just _ -> throwError "Skolem variables cannot escape. Consider adding a type signature."
186+ where
187+ findSkolems (Skolem _) = return ()
188+ findSkolems _ = mzero
189+ findRSkolems (RSkolem _) = return ()
190+ findRSkolems _ = mzero
191+
179192setify :: Row -> Row
180193setify = rowFromList . first (M.toList . M.fromList) . rowToList
181194