1
1
mirror of https://github.com/github/semantic.git synced 2024-12-22 06:11:49 +03:00

Define an use an overwritingUnion for environments

Semigroup instances for Map is using `union`, which is left biased and not always the behavior we want when appending environments.
This commit is contained in:
Timothy Clem 2018-03-26 10:43:24 -07:00
parent b8d6881f75
commit 15ec233467
2 changed files with 10 additions and 1 deletions

View File

@ -205,7 +205,7 @@ instance ( Monad m
namespace n env = do
maybeAddr <- lookupEnv n
env' <- maybe (pure mempty) (asNamespaceEnv <=< deref) maybeAddr
pure (injValue (Namespace n (env' <> env)))
pure (injValue (Namespace n (Env.overwritingUnion env' env)))
where asNamespaceEnv v
| Just (Namespace _ env') <- prjValue v = pure env'
| otherwise = fail ("expected " <> show v <> " to be a namespace")

View File

@ -5,6 +5,7 @@ module Data.Abstract.Environment
, bind
, delete
, head
, overwritingUnion
, insert
, lookup
, names
@ -73,6 +74,14 @@ pop (Environment (_ :| a : as)) = Environment (a :| as)
head :: Environment l a -> Environment l a
head (Environment (a :| _)) = Environment (a :| [])
-- | Take the union of two environments. When duplicate keys are found in the
-- name to address map, the second definition wins.
overwritingUnion :: Environment l a -> Environment l a -> Environment l a
overwritingUnion (Environment (a :| as)) (Environment (b :| bs)) =
Environment (combine a b :| alignWith (mergeThese combine) as bs)
where combine = Map.unionWith (flip const)
-- | Extract an association list of bindings from an 'Environment'.
--
-- >>> pairs shadowed