{- |
    Module      :  $Header$
    Description :  Top-Level Environments
    Copyright   :   1999 - 2003 Wolfgang Lux
                    2005        Martin Engelke
                    2011 - 2012 Björn Peemöller
                    2016        Finn Teegen
    License     :  BSD-3-clause

    Maintainer  :  bjp@informatik.uni-kiel.de
    Stability   :  experimental
    Portability :  portable

    The module 'TopEnv' implements environments for qualified and
    possibly ambiguous identifiers. An identifier is ambiguous if two
    different entities are imported under the same name or if a local
    definition uses the same name as an imported entity. Following an idea
    presented in a paper by Diatchki, Jones and Hallgren (2002),
    an identifier is associated with a list of entities in order to handle
    ambiguous names properly.

    In general, two entities are considered equal if the names of their
    original definitions match. However, in the case of algebraic data
    types it is possible to hide some or all of their data constructors on
    import and export, respectively. In this case we have to merge both
    imports such that all data constructors which are visible through any
    import path are visible in the current module. The class
    Entity is used to handle this merge.

    The code in this module ensures that the list of entities returned by
    the functions 'lookupTopEnv' and 'qualLookupTopEnv' contains exactly one
    element for each imported entity regardless of how many times and
    from which module(s) it was imported. Thus, the result of these function
    is a list with exactly one element if and only if the identifier is
    unambiguous. The module names associated with an imported entity identify
    the modules from which the entity was imported.
-}

module Base.TopEnv
  ( -- * Data types
    TopEnv (..), Entity (..)
    -- * creation and insertion
  , emptyTopEnv, predefTopEnv, importTopEnv, qualImportTopEnv
  , bindTopEnv, qualBindTopEnv, rebindTopEnv
  , qualRebindTopEnv, unbindTopEnv, qualUnbindTopEnv
  , lookupTopEnv, qualLookupTopEnv, qualElemTopEnv
  , allImports, moduleImports, localBindings, allLocalBindings, allBindings
  , allEntities
  ) where

import           Control.Arrow        (second)
import qualified Data.Map      as Map
  (Map, empty, insert, findWithDefault, lookup, toList)

import Curry.Base.Ident
import Base.Messages (internalError)

class Entity a where
 origName :: a -> QualIdent
 merge    :: a -> a -> Maybe a
 merge x :: a
x y :: a
y
   | a -> QualIdent
forall a. Entity a => a -> QualIdent
origName a
x QualIdent -> QualIdent -> Bool
forall a. Eq a => a -> a -> Bool
== a -> QualIdent
forall a. Entity a => a -> QualIdent
origName a
y = a -> Maybe a
forall a. a -> Maybe a
Just a
x
   | Bool
otherwise                = Maybe a
forall a. Maybe a
Nothing

data Source = Local | Import [ModuleIdent] deriving (Source -> Source -> Bool
(Source -> Source -> Bool)
-> (Source -> Source -> Bool) -> Eq Source
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Source -> Source -> Bool
$c/= :: Source -> Source -> Bool
== :: Source -> Source -> Bool
$c== :: Source -> Source -> Bool
Eq, Int -> Source -> ShowS
[Source] -> ShowS
Source -> String
(Int -> Source -> ShowS)
-> (Source -> String) -> ([Source] -> ShowS) -> Show Source
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Source] -> ShowS
$cshowList :: [Source] -> ShowS
show :: Source -> String
$cshow :: Source -> String
showsPrec :: Int -> Source -> ShowS
$cshowsPrec :: Int -> Source -> ShowS
Show)

-- |Top level environment
newtype TopEnv a = TopEnv { TopEnv a -> Map QualIdent [(Source, a)]
topEnvMap :: Map.Map QualIdent [(Source, a)] }
  deriving Int -> TopEnv a -> ShowS
[TopEnv a] -> ShowS
TopEnv a -> String
(Int -> TopEnv a -> ShowS)
-> (TopEnv a -> String) -> ([TopEnv a] -> ShowS) -> Show (TopEnv a)
forall a. Show a => Int -> TopEnv a -> ShowS
forall a. Show a => [TopEnv a] -> ShowS
forall a. Show a => TopEnv a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TopEnv a] -> ShowS
$cshowList :: forall a. Show a => [TopEnv a] -> ShowS
show :: TopEnv a -> String
$cshow :: forall a. Show a => TopEnv a -> String
showsPrec :: Int -> TopEnv a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> TopEnv a -> ShowS
Show

instance Functor TopEnv where
  fmap :: (a -> b) -> TopEnv a -> TopEnv b
fmap f :: a -> b
f (TopEnv env :: Map QualIdent [(Source, a)]
env) = Map QualIdent [(Source, b)] -> TopEnv b
forall a. Map QualIdent [(Source, a)] -> TopEnv a
TopEnv (([(Source, a)] -> [(Source, b)])
-> Map QualIdent [(Source, a)] -> Map QualIdent [(Source, b)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Source, a) -> (Source, b)) -> [(Source, a)] -> [(Source, b)]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> b) -> (Source, a) -> (Source, b)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second a -> b
f)) Map QualIdent [(Source, a)]
env)

-- local helper
entities :: QualIdent -> Map.Map QualIdent [(Source, a)] -> [(Source, a)]
entities :: QualIdent -> Map QualIdent [(Source, a)] -> [(Source, a)]
entities = [(Source, a)]
-> QualIdent -> Map QualIdent [(Source, a)] -> [(Source, a)]
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault []

-- |Empty 'TopEnv'
emptyTopEnv :: TopEnv a
emptyTopEnv :: TopEnv a
emptyTopEnv = Map QualIdent [(Source, a)] -> TopEnv a
forall a. Map QualIdent [(Source, a)] -> TopEnv a
TopEnv Map QualIdent [(Source, a)]
forall k a. Map k a
Map.empty

-- |Insert an 'Entity' into a 'TopEnv' as a predefined 'Entity'
predefTopEnv :: QualIdent -> a -> TopEnv a -> TopEnv a
predefTopEnv :: QualIdent -> a -> TopEnv a -> TopEnv a
predefTopEnv k :: QualIdent
k v :: a
v (TopEnv env :: Map QualIdent [(Source, a)]
env) = case QualIdent -> Map QualIdent [(Source, a)] -> Maybe [(Source, a)]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup QualIdent
k Map QualIdent [(Source, a)]
env of
  Just  _ -> String -> TopEnv a
forall a. String -> a
internalError (String -> TopEnv a) -> String -> TopEnv a
forall a b. (a -> b) -> a -> b
$ "TopEnv.predefTopEnv " String -> ShowS
forall a. [a] -> [a] -> [a]
++ QualIdent -> String
forall a. Show a => a -> String
show QualIdent
k
  Nothing -> Map QualIdent [(Source, a)] -> TopEnv a
forall a. Map QualIdent [(Source, a)] -> TopEnv a
TopEnv (Map QualIdent [(Source, a)] -> TopEnv a)
-> Map QualIdent [(Source, a)] -> TopEnv a
forall a b. (a -> b) -> a -> b
$ QualIdent
-> [(Source, a)]
-> Map QualIdent [(Source, a)]
-> Map QualIdent [(Source, a)]
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert QualIdent
k [([ModuleIdent] -> Source
Import [], a
v)] Map QualIdent [(Source, a)]
env

-- |Insert an 'Entity' as unqualified into a 'TopEnv'
importTopEnv :: Entity a => ModuleIdent -> Ident -> a -> TopEnv a
             -> TopEnv a
importTopEnv :: ModuleIdent -> Ident -> a -> TopEnv a -> TopEnv a
importTopEnv m :: ModuleIdent
m x :: Ident
x y :: a
y env :: TopEnv a
env = ModuleIdent -> QualIdent -> a -> TopEnv a -> TopEnv a
forall a.
Entity a =>
ModuleIdent -> QualIdent -> a -> TopEnv a -> TopEnv a
addImport ModuleIdent
m (Ident -> QualIdent
qualify Ident
x) a
y TopEnv a
env

-- |Insert an 'Entity' as qualified into a 'TopEnv'
qualImportTopEnv :: Entity a => ModuleIdent -> Ident -> a -> TopEnv a
                 -> TopEnv a
qualImportTopEnv :: ModuleIdent -> Ident -> a -> TopEnv a -> TopEnv a
qualImportTopEnv m :: ModuleIdent
m x :: Ident
x y :: a
y env :: TopEnv a
env = ModuleIdent -> QualIdent -> a -> TopEnv a -> TopEnv a
forall a.
Entity a =>
ModuleIdent -> QualIdent -> a -> TopEnv a -> TopEnv a
addImport ModuleIdent
m (ModuleIdent -> Ident -> QualIdent
qualifyWith ModuleIdent
m Ident
x) a
y TopEnv a
env

-- local helper
addImport :: Entity a => ModuleIdent -> QualIdent -> a -> TopEnv a
          -> TopEnv a
addImport :: ModuleIdent -> QualIdent -> a -> TopEnv a -> TopEnv a
addImport m :: ModuleIdent
m k :: QualIdent
k v :: a
v (TopEnv env :: Map QualIdent [(Source, a)]
env) = Map QualIdent [(Source, a)] -> TopEnv a
forall a. Map QualIdent [(Source, a)] -> TopEnv a
TopEnv (Map QualIdent [(Source, a)] -> TopEnv a)
-> Map QualIdent [(Source, a)] -> TopEnv a
forall a b. (a -> b) -> a -> b
$
  QualIdent
-> [(Source, a)]
-> Map QualIdent [(Source, a)]
-> Map QualIdent [(Source, a)]
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert QualIdent
k (a -> [(Source, a)] -> [(Source, a)]
forall a. Entity a => a -> [(Source, a)] -> [(Source, a)]
mergeImport a
v (QualIdent -> Map QualIdent [(Source, a)] -> [(Source, a)]
forall a. QualIdent -> Map QualIdent [(Source, a)] -> [(Source, a)]
entities QualIdent
k Map QualIdent [(Source, a)]
env)) Map QualIdent [(Source, a)]
env
  where
  mergeImport :: Entity a => a -> [(Source, a)] -> [(Source, a)]
  mergeImport :: a -> [(Source, a)] -> [(Source, a)]
mergeImport y :: a
y []                         = [([ModuleIdent] -> Source
Import [ModuleIdent
m], a
y)]
  mergeImport y :: a
y (loc :: (Source, a)
loc@(Local    ,  _) : xs :: [(Source, a)]
xs) = (Source, a)
loc (Source, a) -> [(Source, a)] -> [(Source, a)]
forall a. a -> [a] -> [a]
: a -> [(Source, a)] -> [(Source, a)]
forall a. Entity a => a -> [(Source, a)] -> [(Source, a)]
mergeImport a
y [(Source, a)]
xs
  mergeImport y :: a
y (imp :: (Source, a)
imp@(Import ms :: [ModuleIdent]
ms, y' :: a
y') : xs :: [(Source, a)]
xs) = case a -> a -> Maybe a
forall a. Entity a => a -> a -> Maybe a
merge a
y a
y' of
    Just y'' :: a
y'' -> ([ModuleIdent] -> Source
Import (ModuleIdent
m ModuleIdent -> [ModuleIdent] -> [ModuleIdent]
forall a. a -> [a] -> [a]
: [ModuleIdent]
ms), a
y'') (Source, a) -> [(Source, a)] -> [(Source, a)]
forall a. a -> [a] -> [a]
: [(Source, a)]
xs
    Nothing  -> (Source, a)
imp (Source, a) -> [(Source, a)] -> [(Source, a)]
forall a. a -> [a] -> [a]
: a -> [(Source, a)] -> [(Source, a)]
forall a. Entity a => a -> [(Source, a)] -> [(Source, a)]
mergeImport a
y [(Source, a)]
xs

bindTopEnv :: Ident -> a -> TopEnv a -> TopEnv a
bindTopEnv :: Ident -> a -> TopEnv a -> TopEnv a
bindTopEnv x :: Ident
x y :: a
y env :: TopEnv a
env = QualIdent -> a -> TopEnv a -> TopEnv a
forall a. QualIdent -> a -> TopEnv a -> TopEnv a
qualBindTopEnv (Ident -> QualIdent
qualify Ident
x) a
y TopEnv a
env

qualBindTopEnv :: QualIdent -> a -> TopEnv a -> TopEnv a
qualBindTopEnv :: QualIdent -> a -> TopEnv a -> TopEnv a
qualBindTopEnv x :: QualIdent
x y :: a
y (TopEnv env :: Map QualIdent [(Source, a)]
env)
  = Map QualIdent [(Source, a)] -> TopEnv a
forall a. Map QualIdent [(Source, a)] -> TopEnv a
TopEnv (Map QualIdent [(Source, a)] -> TopEnv a)
-> Map QualIdent [(Source, a)] -> TopEnv a
forall a b. (a -> b) -> a -> b
$ QualIdent
-> [(Source, a)]
-> Map QualIdent [(Source, a)]
-> Map QualIdent [(Source, a)]
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert QualIdent
x (a -> [(Source, a)] -> [(Source, a)]
forall b. b -> [(Source, b)] -> [(Source, b)]
bindLocal a
y (QualIdent -> Map QualIdent [(Source, a)] -> [(Source, a)]
forall a. QualIdent -> Map QualIdent [(Source, a)] -> [(Source, a)]
entities QualIdent
x Map QualIdent [(Source, a)]
env)) Map QualIdent [(Source, a)]
env
  where
  bindLocal :: b -> [(Source, b)] -> [(Source, b)]
bindLocal y' :: b
y' ys :: [(Source, b)]
ys
    | [b] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ b
y'' | (Local, y'' :: b
y'') <- [(Source, b)]
ys ] = (Source
Local, b
y') (Source, b) -> [(Source, b)] -> [(Source, b)]
forall a. a -> [a] -> [a]
: [(Source, b)]
ys
    | Bool
otherwise = String -> [(Source, b)]
forall a. String -> a
internalError (String -> [(Source, b)]) -> String -> [(Source, b)]
forall a b. (a -> b) -> a -> b
$ "qualBindTopEnv " String -> ShowS
forall a. [a] -> [a] -> [a]
++ QualIdent -> String
forall a. Show a => a -> String
show QualIdent
x

rebindTopEnv :: Ident -> a -> TopEnv a -> TopEnv a
rebindTopEnv :: Ident -> a -> TopEnv a -> TopEnv a
rebindTopEnv = QualIdent -> a -> TopEnv a -> TopEnv a
forall a. QualIdent -> a -> TopEnv a -> TopEnv a
qualRebindTopEnv (QualIdent -> a -> TopEnv a -> TopEnv a)
-> (Ident -> QualIdent) -> Ident -> a -> TopEnv a -> TopEnv a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ident -> QualIdent
qualify

qualRebindTopEnv :: QualIdent -> a -> TopEnv a -> TopEnv a
qualRebindTopEnv :: QualIdent -> a -> TopEnv a -> TopEnv a
qualRebindTopEnv x :: QualIdent
x y :: a
y (TopEnv env :: Map QualIdent [(Source, a)]
env) =
  Map QualIdent [(Source, a)] -> TopEnv a
forall a. Map QualIdent [(Source, a)] -> TopEnv a
TopEnv (Map QualIdent [(Source, a)] -> TopEnv a)
-> Map QualIdent [(Source, a)] -> TopEnv a
forall a b. (a -> b) -> a -> b
$ QualIdent
-> [(Source, a)]
-> Map QualIdent [(Source, a)]
-> Map QualIdent [(Source, a)]
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert QualIdent
x ([(Source, a)] -> [(Source, a)]
rebindLocal (QualIdent -> Map QualIdent [(Source, a)] -> [(Source, a)]
forall a. QualIdent -> Map QualIdent [(Source, a)] -> [(Source, a)]
entities QualIdent
x Map QualIdent [(Source, a)]
env)) Map QualIdent [(Source, a)]
env
  where
  rebindLocal :: [(Source, a)] -> [(Source, a)]
rebindLocal []                = String -> [(Source, a)]
forall a. String -> a
internalError
                                (String -> [(Source, a)]) -> String -> [(Source, a)]
forall a b. (a -> b) -> a -> b
$ "TopEnv.qualRebindTopEnv " String -> ShowS
forall a. [a] -> [a] -> [a]
++ QualIdent -> String
forall a. Show a => a -> String
show QualIdent
x
  rebindLocal ((Local, _) : ys :: [(Source, a)]
ys) = (Source
Local, a
y) (Source, a) -> [(Source, a)] -> [(Source, a)]
forall a. a -> [a] -> [a]
: [(Source, a)]
ys
  rebindLocal (imported :: (Source, a)
imported   : ys :: [(Source, a)]
ys) = (Source, a)
imported   (Source, a) -> [(Source, a)] -> [(Source, a)]
forall a. a -> [a] -> [a]
: [(Source, a)] -> [(Source, a)]
rebindLocal [(Source, a)]
ys

unbindTopEnv :: Ident -> TopEnv a -> TopEnv a
unbindTopEnv :: Ident -> TopEnv a -> TopEnv a
unbindTopEnv x :: Ident
x (TopEnv env :: Map QualIdent [(Source, a)]
env) =
  Map QualIdent [(Source, a)] -> TopEnv a
forall a. Map QualIdent [(Source, a)] -> TopEnv a
TopEnv (Map QualIdent [(Source, a)] -> TopEnv a)
-> Map QualIdent [(Source, a)] -> TopEnv a
forall a b. (a -> b) -> a -> b
$ QualIdent
-> [(Source, a)]
-> Map QualIdent [(Source, a)]
-> Map QualIdent [(Source, a)]
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert QualIdent
x' ([(Source, a)] -> [(Source, a)]
forall b. [(Source, b)] -> [(Source, b)]
unbindLocal (QualIdent -> Map QualIdent [(Source, a)] -> [(Source, a)]
forall a. QualIdent -> Map QualIdent [(Source, a)] -> [(Source, a)]
entities QualIdent
x' Map QualIdent [(Source, a)]
env)) Map QualIdent [(Source, a)]
env
  where x' :: QualIdent
x' = Ident -> QualIdent
qualify Ident
x
        unbindLocal :: [(Source, b)] -> [(Source, b)]
unbindLocal [] = String -> [(Source, b)]
forall a. String -> a
internalError (String -> [(Source, b)]) -> String -> [(Source, b)]
forall a b. (a -> b) -> a -> b
$ "TopEnv.unbindTopEnv " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Ident -> String
forall a. Show a => a -> String
show Ident
x
        unbindLocal ((Local, _) : ys :: [(Source, b)]
ys) = [(Source, b)]
ys
        unbindLocal (imported :: (Source, b)
imported   : ys :: [(Source, b)]
ys) = (Source, b)
imported (Source, b) -> [(Source, b)] -> [(Source, b)]
forall a. a -> [a] -> [a]
: [(Source, b)] -> [(Source, b)]
unbindLocal [(Source, b)]
ys

qualUnbindTopEnv :: QualIdent -> TopEnv a -> TopEnv a
qualUnbindTopEnv :: QualIdent -> TopEnv a -> TopEnv a
qualUnbindTopEnv x :: QualIdent
x (TopEnv env :: Map QualIdent [(Source, a)]
env) =
  Map QualIdent [(Source, a)] -> TopEnv a
forall a. Map QualIdent [(Source, a)] -> TopEnv a
TopEnv (Map QualIdent [(Source, a)] -> TopEnv a)
-> Map QualIdent [(Source, a)] -> TopEnv a
forall a b. (a -> b) -> a -> b
$ QualIdent
-> [(Source, a)]
-> Map QualIdent [(Source, a)]
-> Map QualIdent [(Source, a)]
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert QualIdent
x ([(Source, a)] -> [(Source, a)]
forall a a. [a] -> [a]
unbind (QualIdent -> Map QualIdent [(Source, a)] -> [(Source, a)]
forall a. QualIdent -> Map QualIdent [(Source, a)] -> [(Source, a)]
entities QualIdent
x Map QualIdent [(Source, a)]
env)) Map QualIdent [(Source, a)]
env
  where unbind :: [a] -> [a]
unbind [] = String -> [a]
forall a. String -> a
internalError (String -> [a]) -> String -> [a]
forall a b. (a -> b) -> a -> b
$ "TopEnv.qualUnbindTopEnv " String -> ShowS
forall a. [a] -> [a] -> [a]
++ QualIdent -> String
forall a. Show a => a -> String
show QualIdent
x
        unbind _  = []

lookupTopEnv :: Ident -> TopEnv a -> [a]
lookupTopEnv :: Ident -> TopEnv a -> [a]
lookupTopEnv = QualIdent -> TopEnv a -> [a]
forall a. QualIdent -> TopEnv a -> [a]
qualLookupTopEnv (QualIdent -> TopEnv a -> [a])
-> (Ident -> QualIdent) -> Ident -> TopEnv a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ident -> QualIdent
qualify

qualLookupTopEnv :: QualIdent -> TopEnv a -> [a]
qualLookupTopEnv :: QualIdent -> TopEnv a -> [a]
qualLookupTopEnv x :: QualIdent
x (TopEnv env :: Map QualIdent [(Source, a)]
env) = ((Source, a) -> a) -> [(Source, a)] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (Source, a) -> a
forall a b. (a, b) -> b
snd (QualIdent -> Map QualIdent [(Source, a)] -> [(Source, a)]
forall a. QualIdent -> Map QualIdent [(Source, a)] -> [(Source, a)]
entities QualIdent
x Map QualIdent [(Source, a)]
env)

qualElemTopEnv :: QualIdent -> TopEnv a -> Bool
qualElemTopEnv :: QualIdent -> TopEnv a -> Bool
qualElemTopEnv x :: QualIdent
x env :: TopEnv a
env = Bool -> Bool
not ([a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (QualIdent -> TopEnv a -> [a]
forall a. QualIdent -> TopEnv a -> [a]
qualLookupTopEnv QualIdent
x TopEnv a
env))

allImports :: TopEnv a -> [(QualIdent, a)]
allImports :: TopEnv a -> [(QualIdent, a)]
allImports (TopEnv env :: Map QualIdent [(Source, a)]
env) =
  [ (QualIdent
x, a
y) | (x :: QualIdent
x, ys :: [(Source, a)]
ys) <- Map QualIdent [(Source, a)] -> [(QualIdent, [(Source, a)])]
forall k a. Map k a -> [(k, a)]
Map.toList Map QualIdent [(Source, a)]
env, (Import _, y :: a
y) <- [(Source, a)]
ys ]

unqualBindings :: TopEnv a -> [(Ident, (Source, a))]
unqualBindings :: TopEnv a -> [(Ident, (Source, a))]
unqualBindings (TopEnv env :: Map QualIdent [(Source, a)]
env) =
  [ (Ident
x', (Source, a)
y) | (x :: QualIdent
x, ys :: [(Source, a)]
ys) <- ((QualIdent, [(Source, a)]) -> Bool)
-> [(QualIdent, [(Source, a)])] -> [(QualIdent, [(Source, a)])]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> ((QualIdent, [(Source, a)]) -> Bool)
-> (QualIdent, [(Source, a)])
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QualIdent -> Bool
isQualified (QualIdent -> Bool)
-> ((QualIdent, [(Source, a)]) -> QualIdent)
-> (QualIdent, [(Source, a)])
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QualIdent, [(Source, a)]) -> QualIdent
forall a b. (a, b) -> a
fst) (Map QualIdent [(Source, a)] -> [(QualIdent, [(Source, a)])]
forall k a. Map k a -> [(k, a)]
Map.toList Map QualIdent [(Source, a)]
env)
            , let x' :: Ident
x' = QualIdent -> Ident
unqualify QualIdent
x, (Source, a)
y <- [(Source, a)]
ys]

moduleImports :: ModuleIdent -> TopEnv a -> [(Ident, a)]
moduleImports :: ModuleIdent -> TopEnv a -> [(Ident, a)]
moduleImports m :: ModuleIdent
m env :: TopEnv a
env =
  [(Ident
x, a
y) | (x :: Ident
x, (Import ms :: [ModuleIdent]
ms, y :: a
y)) <- TopEnv a -> [(Ident, (Source, a))]
forall a. TopEnv a -> [(Ident, (Source, a))]
unqualBindings TopEnv a
env, ModuleIdent
m ModuleIdent -> [ModuleIdent] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ModuleIdent]
ms]

localBindings :: TopEnv a -> [(Ident, a)]
localBindings :: TopEnv a -> [(Ident, a)]
localBindings env :: TopEnv a
env = [ (Ident
x, a
y) | (x :: Ident
x, (Local, y :: a
y)) <- TopEnv a -> [(Ident, (Source, a))]
forall a. TopEnv a -> [(Ident, (Source, a))]
unqualBindings TopEnv a
env ]

allLocalBindings :: TopEnv a -> [(QualIdent, a)]
allLocalBindings :: TopEnv a -> [(QualIdent, a)]
allLocalBindings (TopEnv env :: Map QualIdent [(Source, a)]
env) = [ (QualIdent
x, a
y) | (x :: QualIdent
x, ys :: [(Source, a)]
ys)    <- Map QualIdent [(Source, a)] -> [(QualIdent, [(Source, a)])]
forall k a. Map k a -> [(k, a)]
Map.toList Map QualIdent [(Source, a)]
env
                                         , (Local, y :: a
y) <- [(Source, a)]
ys ]

allBindings :: TopEnv a -> [(QualIdent, a)]
allBindings :: TopEnv a -> [(QualIdent, a)]
allBindings (TopEnv env :: Map QualIdent [(Source, a)]
env) = [(QualIdent
x, a
y) | (x :: QualIdent
x, ys :: [(Source, a)]
ys) <- Map QualIdent [(Source, a)] -> [(QualIdent, [(Source, a)])]
forall k a. Map k a -> [(k, a)]
Map.toList Map QualIdent [(Source, a)]
env, (_, y :: a
y) <- [(Source, a)]
ys]

allEntities :: TopEnv a -> [a]
allEntities :: TopEnv a -> [a]
allEntities (TopEnv env :: Map QualIdent [(Source, a)]
env) = [ a
y | (_, ys :: [(Source, a)]
ys) <- Map QualIdent [(Source, a)] -> [(QualIdent, [(Source, a)])]
forall k a. Map k a -> [(k, a)]
Map.toList Map QualIdent [(Source, a)]
env, (_, y :: a
y) <- [(Source, a)]
ys]