The use of liftM2 (<|>) was executing too much of both arguments

This is demonstrated by the following example, courtesy of Ryan Trinkle:

    let x = with x; with { a = 5; }; a; in x

Although the dynamic scopes visible at 'a' happen to be [<thunk: { a = 5; }>,
<thunk: x>], we were forcing each thunk before doing the M.lookup, and then
performing (<|>) on the M.lookup.

Fixes #347
This commit is contained in:
John Wiegley 2018-09-07 13:08:30 -07:00
parent 7d549d67c6
commit 99626e9ab9
No known key found for this signature in database
GPG key ID: C144D8F4F19FE630

View file

@ -76,7 +76,11 @@ lookupVar k = do
Just sym -> return $ Just sym
Nothing -> do
ws <- asks (dynamicScopes . view hasLens)
foldr (\x -> liftM2 (<|>) (M.lookup k . getScope <$> x))
foldr (\x rest -> do
mres' <- M.lookup k . getScope <$> x
case mres' of
Just sym -> return $ Just sym
Nothing -> rest)
(return Nothing) ws
withScopes :: forall v m e a. Scoped e v m => Scopes m v -> m a -> m a