content: {-# LANGUAGE CPP #-}
  
  module Mueval.Context (
      cleanModules,
      defaultModules,
      defaultPackages,
      qualifiedModules,
  ) where
  
  -----------------------------------------------------------------------------
  
  -- | Return false if any of the listed modules cannot be found in the whitelist.
  cleanModules :: [String] -> Bool
  cleanModules = all (`elem` defaultModules)
  
  {- | Modules which we should load by default. These are of course whitelisted.
     Specifically, we want the Prelude because otherwise things are horribly
     crippled; we want SimpleReflect so we can do neat things (for said neat
     things, see
     <http://twan.home.fmf.nl/blog/haskell/simple-reflection-of-expressions.details>);
     and we want ShowFun to neuter IO stuff even more.
     The rest should be safe to import without clashes, according to the Lambdabot
     sources.
  -}
  defaultModules :: [String]
  defaultModules =
      [ "Prelude"
      , "ShowFun"
      , "Debug.SimpleReflect"
      , "Data.Function"
      , "Control.Applicative"
      , "Control.Arrow"
      , "Control.Monad"
      , "Control.Monad.Cont"
  #if __GLASGOW_HASKELL__ >= 710
      , "Control.Monad.Except"
  #else
      , "Control.Monad.Error"
  #endif
      , "Control.Monad.Fix"
      , "Control.Monad.Identity"
  #if !MIN_VERSION_base(4,7,0)
      , "Control.Monad.Instances"
  #endif
      , "Control.Monad.RWS"
      , "Control.Monad.Reader"
      , "Control.Monad.State"
      , "Control.Monad.State"
      , "Control.Monad.Writer"
      , "Data.Array"
      , "Data.Bits"
      , "Data.Bool"
      , "Data.Char"
      , "Data.Complex"
      , "Data.Dynamic"
      , "Data.Either"
      , "Data.Eq"
      , "Data.Fixed"
      , "Data.Graph"
      , "Data.Int"
      , "Data.Ix"
      , "Data.List"
      , "Data.Maybe"
      , "Data.Monoid"
      , {- -- Commented out because they are not necessarily available. If anyone misses
           -- them, perhaps we could look into forcing a dependency on them in the Cabal
           -- file or perhaps enable them via a CLI flag. For now, we'll stash them in a comment.
                       "Control.Parallel",
                       "Control.Parallel.Strategies",
                       "Data.Number.BigFloat",
                       "Data.Number.CReal",
                       "Data.Number.Dif",
                       "Data.Number.Fixed",
                       "Data.Number.Interval",
                       "Data.Number.Natural",
                       "Data.Number.Symbolic",
                       "Math.OEIS",
        -}
        "Data.Ord"
      , "Data.Ratio"
      , "Data.Tree"
      , "Data.Tuple"
      , "Data.Typeable"
      , "Data.Word"
      , "System.Random"
      , "Test.QuickCheck"
      , "Text.PrettyPrint.HughesPJ"
      , "Text.Printf"
      ]
  
  defaultPackages :: [String]
  defaultPackages =
      [ "array"
      , "base"
      , "bytestring"
      , "containers"
      ]
  
  {- | Borrowed from Lambdabot, this is the whitelist of modules which should be
     safe to import functions from, but which we don't want to import by
     default.
     FIXME: make these qualified imports. The GHC API & Hint currently do not
     support qualified imports.
     WARNING: You can import these with --module, certainly, but the onus is on
     the user to make sure they fully disambiguate function names; ie:
  
     > mueval  --module Data.Map -e "Prelude.map (+1) [1..100]"
  -}
  qualifiedModules :: [(String, Maybe String)]
  qualifiedModules =
      [ --                ("Control.Arrow.Transformer", Just "AT"),
        --                ("Control.Arrow.Transformer.All", Just "AT"),
        ("Data.ByteString", Just "BS")
      , ("Data.ByteString.Char8", Just "BSC")
      , ("Data.ByteString.Lazy", Just "BSL")
      , ("Data.ByteString.Lazy.Char8", Just "BSLC")
      , ("Data.Foldable", Just "Data.Foldable")
      , --               ("Data.Generics", Just "Data.Generics"),
        ("Data.IntMap", Just "IM")
      , ("Data.IntSet", Just "IS")
      , ("Data.Map", Just "M")
      , ("Data.Sequence", Just "Data.Sequence")
      , ("Data.Set", Just "S")
      , ("Data.Traversable", Just "Data.Traversable")
      ]
  