    -- | Convenient common interface for command line Futhark compilers.
    -- Using this module ensures that all compilers take the same options.
    -- A small amount of flexibility is provided for backend-specific
    -- options.
    module Futhark.Compiler.CLI
      ( compilerMain,
        CompilerOption,
        CompilerMode (..),
        module Futhark.Pipeline,
        module Futhark.Compiler,
      )
    where

    import Control.Monad
    import Data.Maybe
    import Futhark.Compiler
    import Futhark.IR (Name, Prog, nameFromString)
    import Futhark.IR.SOACS (SOACS)
    import Futhark.Pipeline
    import Futhark.Util.Options
    import System.FilePath

    -- | Run a parameterised Futhark compiler, where @cfg@ is a user-given
    -- configuration type.  Call this from @main@.
    compilerMain ::
      -- | Initial configuration.
      cfg ->
      -- | Options that affect the configuration.
      [CompilerOption cfg] ->
      -- | The short action name (e.g. "compile to C").
      String ->
      -- | The longer action description.
      String ->
      -- | The pipeline to use.
      Pipeline SOACS rep ->
      -- | The action to take on the result of the pipeline.
      ( FutharkConfig ->
        cfg ->
        CompilerMode ->
        FilePath ->
        Prog rep ->
        FutharkM ()
      ) ->
      -- | Program name
      String ->
      -- | Command line arguments.
      [String] ->
      IO ()
    compilerMain :: forall cfg rep.
    cfg
    -> [CompilerOption cfg]
    -> String
    -> String
    -> Pipeline SOACS rep
    -> (FutharkConfig
        -> cfg -> CompilerMode -> String -> Prog rep -> FutharkM ())
    -> String
    -> [String]
    -> IO ()
    compilerMain cfg
    cfg [CompilerOption cfg]
    cfg_opts String
    name String
    desc Pipeline SOACS rep
    pipeline FutharkConfig
    -> cfg -> CompilerMode -> String -> Prog rep -> FutharkM ()
    doIt =
      CompilerConfig cfg
    -> [FunOptDescr (CompilerConfig cfg)]
    -> String
    -> ([String] -> CompilerConfig cfg -> Maybe (IO ()))
    -> String
    -> [String]
    -> IO ()
    forall cfg.
    cfg
    -> [FunOptDescr cfg]
    -> String
    -> ([String] -> cfg -> Maybe (IO ()))
    -> String
    -> [String]
    -> IO ()
    mainWithOptions
        (cfg -> CompilerConfig cfg
    forall cfg. cfg -> CompilerConfig cfg
    newCompilerConfig cfg
    cfg)
        ([FunOptDescr (CompilerConfig cfg)]
    forall cfg. [CoreCompilerOption cfg]
    commandLineOptions [FunOptDescr (CompilerConfig cfg)]
    -> [FunOptDescr (CompilerConfig cfg)]
    -> [FunOptDescr (CompilerConfig cfg)]
    forall a. [a] -> [a] -> [a]
    ++ (CompilerOption cfg -> FunOptDescr (CompilerConfig cfg))
    -> [CompilerOption cfg] -> [FunOptDescr (CompilerConfig cfg)]
    forall a b. (a -> b) -> [a] -> [b]
    map CompilerOption cfg -> FunOptDescr (CompilerConfig cfg)
    forall cfg. CompilerOption cfg -> CoreCompilerOption cfg
    wrapOption [CompilerOption cfg]
    cfg_opts)
        String
    "options... <program.fut>"
        [String] -> CompilerConfig cfg -> Maybe (IO ())
    inspectNonOptions
      where
        inspectNonOptions :: [String] -> CompilerConfig cfg -> Maybe (IO ())
    inspectNonOptions [String
    file] CompilerConfig cfg
    config = IO () -> Maybe (IO ())
    forall a. a -> Maybe a
    Just (IO () -> Maybe (IO ())) -> IO () -> Maybe (IO ())
    forall a b. (a -> b) -> a -> b
    $ CompilerConfig cfg -> String -> IO ()
    compile CompilerConfig cfg
    config String
    file
        inspectNonOptions [String]
    _ CompilerConfig cfg
    _ = Maybe (IO ())
    forall a. Maybe a
    Nothing

        compile :: CompilerConfig cfg -> String -> IO ()
    compile CompilerConfig cfg
    config String
    filepath =
          FutharkConfig
    -> Pipeline SOACS rep -> Action rep -> String -> IO ()
    forall rep.
    FutharkConfig
    -> Pipeline SOACS rep -> Action rep -> String -> IO ()
    runCompilerOnProgram
            (CompilerConfig cfg -> FutharkConfig
    forall cfg. CompilerConfig cfg -> FutharkConfig
    futharkConfig CompilerConfig cfg
    config)
            Pipeline SOACS rep
    pipeline
            (CompilerConfig cfg -> String -> Action rep
    action CompilerConfig cfg
    config String
    filepath)
            String
    filepath

        action :: CompilerConfig cfg -> String -> Action rep
    action CompilerConfig cfg
    config String
    filepath =
          Action
            { actionName :: String
    actionName = String
    name,
              actionDescription :: String
    actionDescription = String
    desc,
              actionProcedure :: Prog rep -> FutharkM ()
    actionProcedure =
                FutharkConfig
    -> cfg -> CompilerMode -> String -> Prog rep -> FutharkM ()
    doIt
                  (CompilerConfig cfg -> FutharkConfig
    forall cfg. CompilerConfig cfg -> FutharkConfig
    futharkConfig CompilerConfig cfg
    config)
                  (CompilerConfig cfg -> cfg
    forall cfg. CompilerConfig cfg -> cfg
    compilerConfig CompilerConfig cfg
    config)
                  (CompilerConfig cfg -> CompilerMode
    forall cfg. CompilerConfig cfg -> CompilerMode
    compilerMode CompilerConfig cfg
    config)
                  (String -> CompilerConfig cfg -> String
    forall cfg. String -> CompilerConfig cfg -> String
    outputFilePath String
    filepath CompilerConfig cfg
    config)
            }

    -- | An option that modifies the configuration of type @cfg@.
    type CompilerOption cfg = OptDescr (Either (IO ()) (cfg -> cfg))

    type CoreCompilerOption cfg =
      OptDescr
        ( Either
            (IO ())
            (CompilerConfig cfg -> CompilerConfig cfg)
        )

    commandLineOptions :: [CoreCompilerOption cfg]
    commandLineOptions :: forall cfg. [CoreCompilerOption cfg]
    commandLineOptions =
      [ String
    -> [String]
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> String
    -> CoreCompilerOption cfg
    forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
    Option
          String
    "o"
          []
          ( (String
     -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> String
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a. (String -> a) -> String -> ArgDescr a
    ReqArg
              (\String
    filename -> (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. b -> Either a b
    Right ((CompilerConfig cfg -> CompilerConfig cfg)
     -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. (a -> b) -> a -> b
    $ \CompilerConfig cfg
    config -> CompilerConfig cfg
    config {compilerOutput = Just filename})
              String
    "FILE"
          )
          String
    "Name of the compiled binary.",
        String
    -> [String]
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> String
    -> CoreCompilerOption cfg
    forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
    Option
          String
    "v"
          [String
    "verbose"]
          ((Maybe String
     -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> String
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a. (Maybe String -> a) -> String -> ArgDescr a
    OptArg ((CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. b -> Either a b
    Right ((CompilerConfig cfg -> CompilerConfig cfg)
     -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> (Maybe String -> CompilerConfig cfg -> CompilerConfig cfg)
    -> Maybe String
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Maybe String -> CompilerConfig cfg -> CompilerConfig cfg
    forall cfg.
    Maybe String -> CompilerConfig cfg -> CompilerConfig cfg
    incVerbosity) String
    "FILE")
          String
    "Print verbose output on standard error; wrong program to FILE.",
        String
    -> [String]
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> String
    -> CoreCompilerOption cfg
    forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
    Option
          []
          [String
    "library"]
          (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a. a -> ArgDescr a
    NoArg (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
     -> ArgDescr
          (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)))
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a b. (a -> b) -> a -> b
    $ (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. b -> Either a b
    Right ((CompilerConfig cfg -> CompilerConfig cfg)
     -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. (a -> b) -> a -> b
    $ \CompilerConfig cfg
    config -> CompilerConfig cfg
    config {compilerMode = ToLibrary})
          String
    "Generate a library instead of an executable.",
        String
    -> [String]
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> String
    -> CoreCompilerOption cfg
    forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
    Option
          []
          [String
    "executable"]
          (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a. a -> ArgDescr a
    NoArg (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
     -> ArgDescr
          (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)))
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a b. (a -> b) -> a -> b
    $ (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. b -> Either a b
    Right ((CompilerConfig cfg -> CompilerConfig cfg)
     -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. (a -> b) -> a -> b
    $ \CompilerConfig cfg
    config -> CompilerConfig cfg
    config {compilerMode = ToExecutable})
          String
    "Generate an executable instead of a library (set by default).",
        String
    -> [String]
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> String
    -> CoreCompilerOption cfg
    forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
    Option
          []
          [String
    "server"]
          (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a. a -> ArgDescr a
    NoArg (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
     -> ArgDescr
          (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)))
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a b. (a -> b) -> a -> b
    $ (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. b -> Either a b
    Right ((CompilerConfig cfg -> CompilerConfig cfg)
     -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. (a -> b) -> a -> b
    $ \CompilerConfig cfg
    config -> CompilerConfig cfg
    config {compilerMode = ToServer})
          String
    "Generate a server executable instead of a library.",
        String
    -> [String]
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> String
    -> CoreCompilerOption cfg
    forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
    Option
          String
    "w"
          []
          (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a. a -> ArgDescr a
    NoArg (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
     -> ArgDescr
          (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)))
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a b. (a -> b) -> a -> b
    $ (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. b -> Either a b
    Right ((CompilerConfig cfg -> CompilerConfig cfg)
     -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. (a -> b) -> a -> b
    $ \CompilerConfig cfg
    config -> CompilerConfig cfg
    config {compilerWarn = False})
          String
    "Disable all warnings.",
        String
    -> [String]
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> String
    -> CoreCompilerOption cfg
    forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
    Option
          []
          [String
    "Werror"]
          (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a. a -> ArgDescr a
    NoArg (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
     -> ArgDescr
          (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)))
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a b. (a -> b) -> a -> b
    $ (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. b -> Either a b
    Right ((CompilerConfig cfg -> CompilerConfig cfg)
     -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. (a -> b) -> a -> b
    $ \CompilerConfig cfg
    config -> CompilerConfig cfg
    config {compilerWerror = True})
          String
    "Treat warnings as errors.",
        String
    -> [String]
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> String
    -> CoreCompilerOption cfg
    forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
    Option
          []
          [String
    "safe"]
          (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a. a -> ArgDescr a
    NoArg (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
     -> ArgDescr
          (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)))
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a b. (a -> b) -> a -> b
    $ (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. b -> Either a b
    Right ((CompilerConfig cfg -> CompilerConfig cfg)
     -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. (a -> b) -> a -> b
    $ \CompilerConfig cfg
    config -> CompilerConfig cfg
    config {compilerSafe = True})
          String
    "Ignore 'unsafe' in code.",
        String
    -> [String]
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> String
    -> CoreCompilerOption cfg
    forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
    Option
          []
          [String
    "entry-point"]
          ( (String
     -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> String
    -> ArgDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a. (String -> a) -> String -> ArgDescr a
    ReqArg
              ( \String
    arg -> (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. b -> Either a b
    Right ((CompilerConfig cfg -> CompilerConfig cfg)
     -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> (CompilerConfig cfg -> CompilerConfig cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall a b. (a -> b) -> a -> b
    $ \CompilerConfig cfg
    config ->
                  CompilerConfig cfg
    config
                    { compilerEntryPoints =
                        nameFromString arg : compilerEntryPoints config
                    }
              )
              String
    "NAME"
          )
          String
    "Treat this function as an additional entry point."
      ]

    wrapOption :: CompilerOption cfg -> CoreCompilerOption cfg
    wrapOption :: forall cfg. CompilerOption cfg -> CoreCompilerOption cfg
    wrapOption = (Either (IO ()) (cfg -> cfg)
     -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    -> OptDescr (Either (IO ()) (cfg -> cfg))
    -> OptDescr
         (Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg))
    forall a b. (a -> b) -> OptDescr a -> OptDescr b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Either (IO ()) (cfg -> cfg)
    -> Either (IO ()) (CompilerConfig cfg -> CompilerConfig cfg)
    forall {m :: * -> *} {t} {cfg}.
    Monad m =>
    m (t -> cfg) -> m (CompilerConfig t -> CompilerConfig cfg)
    wrap
      where
        wrap :: m (t -> cfg) -> m (CompilerConfig t -> CompilerConfig cfg)
    wrap m (t -> cfg)
    f = do
          g <- m (t -> cfg)
    f
          pure $ \CompilerConfig t
    cfg -> CompilerConfig t
    cfg {compilerConfig = g (compilerConfig cfg)}

    incVerbosity :: Maybe FilePath -> CompilerConfig cfg -> CompilerConfig cfg
    incVerbosity :: forall cfg.
    Maybe String -> CompilerConfig cfg -> CompilerConfig cfg
    incVerbosity Maybe String
    file CompilerConfig cfg
    cfg =
      CompilerConfig cfg
    cfg {compilerVerbose = (v, file `mplus` snd (compilerVerbose cfg))}
      where
        v :: Verbosity
    v = case (Verbosity, Maybe String) -> Verbosity
    forall a b. (a, b) -> a
    fst ((Verbosity, Maybe String) -> Verbosity)
    -> (Verbosity, Maybe String) -> Verbosity
    forall a b. (a -> b) -> a -> b
    $ CompilerConfig cfg -> (Verbosity, Maybe String)
    forall cfg. CompilerConfig cfg -> (Verbosity, Maybe String)
    compilerVerbose CompilerConfig cfg
    cfg of
          Verbosity
    NotVerbose -> Verbosity
    Verbose
          Verbosity
    Verbose -> Verbosity
    VeryVerbose
          Verbosity
    VeryVerbose -> Verbosity
    VeryVerbose

    data CompilerConfig cfg = CompilerConfig
      { forall cfg. CompilerConfig cfg -> Maybe String
    compilerOutput :: Maybe FilePath,
        forall cfg. CompilerConfig cfg -> (Verbosity, Maybe String)
    compilerVerbose :: (Verbosity, Maybe FilePath),
        forall cfg. CompilerConfig cfg -> CompilerMode
    compilerMode :: CompilerMode,
        forall cfg. CompilerConfig cfg -> Bool
    compilerWerror :: Bool,
        forall cfg. CompilerConfig cfg -> Bool
    compilerSafe :: Bool,
        forall cfg. CompilerConfig cfg -> Bool
    compilerWarn :: Bool,
        forall cfg. CompilerConfig cfg -> cfg
    compilerConfig :: cfg,
        forall cfg. CompilerConfig cfg -> [Name]
    compilerEntryPoints :: [Name]
      }

    -- | The configuration of the compiler.
    newCompilerConfig :: cfg -> CompilerConfig cfg
    newCompilerConfig :: forall cfg. cfg -> CompilerConfig cfg
    newCompilerConfig cfg
    x =
      CompilerConfig
        { compilerOutput :: Maybe String
    compilerOutput = Maybe String
    forall a. Maybe a
    Nothing,
          compilerVerbose :: (Verbosity, Maybe String)
    compilerVerbose = (Verbosity
    NotVerbose, Maybe String
    forall a. Maybe a
    Nothing),
          compilerMode :: CompilerMode
    compilerMode = CompilerMode
    ToExecutable,
          compilerWerror :: Bool
    compilerWerror = Bool
    False,
          compilerSafe :: Bool
    compilerSafe = Bool
    False,
          compilerWarn :: Bool
    compilerWarn = Bool
    True,
          compilerConfig :: cfg
    compilerConfig = cfg
    x,
          compilerEntryPoints :: [Name]
    compilerEntryPoints = [Name]
    forall a. Monoid a => a
    mempty
        }

    outputFilePath :: FilePath -> CompilerConfig cfg -> FilePath
    outputFilePath :: forall cfg. String -> CompilerConfig cfg -> String
    outputFilePath String
    srcfile =
      String -> Maybe String -> String
    forall a. a -> Maybe a -> a
    fromMaybe (String
    srcfile String -> String -> String
    `replaceExtension` String
    "") (Maybe String -> String)
    -> (CompilerConfig cfg -> Maybe String)
    -> CompilerConfig cfg
    -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CompilerConfig cfg -> Maybe String
    forall cfg. CompilerConfig cfg -> Maybe String
    compilerOutput

    futharkConfig :: CompilerConfig cfg -> FutharkConfig
    futharkConfig :: forall cfg. CompilerConfig cfg -> FutharkConfig
    futharkConfig CompilerConfig cfg
    config =
      FutharkConfig
    newFutharkConfig
        { futharkVerbose = compilerVerbose config,
          futharkWerror = compilerWerror config,
          futharkSafe = compilerSafe config,
          futharkWarn = compilerWarn config,
          futharkEntryPoints = compilerEntryPoints config
        }