Поиск пакетов для клики при использовании GHC API

Я пытаюсь создать программу, которая проверяет файлы haskell для меня, используя GHC API. Я получил проверку типов для работы с локальными файлами, но у меня есть специальный пакет cabal, который мне также нужно иметь (тот же пакет, частью которого будет исполняемый файл). Как добавить эту зависимость импорта?

Я также попытался скомпилировать с командной строкой GHC, чтобы понять это, используя ghc -package PKG-VER --make Test.hs -v но это только кажется, что искать в локальном каталоге для импорта.

Мой текущий код выглядит так:

import           Control.Exception
import           Control.Monad
import           Control.Monad.State
import           DynFlags
import           Exception
import           GHC
import           GHC.Paths           (libdir)
typecheck :: MonadIO m => [FilePath] -> FilePath -> m ()
typecheck otherincludes fp =
  liftIO . defaultErrorHandler defaultLogAction . runGhc (Just libdir) $ do
    dynflags <- getSessionDynFlags
    void $ setSessionDynFlags dynflags { includePaths = otherIncludes ++ includePaths dynflags }
    target <- guessTarget fp Nothing
    setTargets [target]
    void $ load LoadAllTargets
    deps <- depanal [] False
    forM_ deps $ \ms -> parseModule ms >>= typecheckModule

1 ответ

Решение

Мне удалось заставить ваш код читать и проверять себя следующим образом:

package Test where
import           Control.Exception
import           Control.Monad
import           Control.Monad.State
import           DynFlags
import           Exception
import           GHC
import           GHC.Paths           (libdir)
typecheck :: MonadIO m => [FilePath] -> FilePath -> m ()
typecheck otherincludes fp =
  liftIO . defaultErrorHandler defaultLogAction . runGhc (Just libdir) $ do
    dynflags <- getSessionDynFlags
    void $ setSessionDynFlags dynflags {
        includePaths = otherincludes ++ includePaths dynflags,
        packageFlags = [ExposePackage "ghc"]} }
    target <- guessTarget fp Nothing
    setTargets [target]
    void $ load LoadAllTargets
    deps <- depanal [] False
    forM_ deps $ \ms -> parseModule ms >>= typecheckModule

Вот как это работает в GHCI:

$ ghci Test.hs -package ghc
GHCi, version 7.4.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package array-0.4.0.0 ... linking ... done.
Loading package deepseq-1.3.0.0 ... linking ... done.
Loading package containers-0.4.2.1 ... linking ... done.
Loading package filepath-1.3.0.0 ... linking ... done.
Loading package old-locale-1.0.0.4 ... linking ... done.
Loading package old-time-1.1.0.0 ... linking ... done.
Loading package bytestring-0.9.2.1 ... linking ... done.
Loading package unix-2.5.1.0 ... linking ... done.
Loading package directory-1.1.0.2 ... linking ... done.
Loading package pretty-1.1.1.0 ... linking ... done.
Loading package process-1.1.0.1 ... linking ... done.
Loading package Cabal-1.14.0 ... linking ... done.
Loading package binary-0.5.1.0 ... linking ... done.
Loading package bin-package-db-0.0.0.0 ... linking ... done.
Loading package hoopl-3.8.7.3 ... linking ... done.
Loading package hpc-0.5.1.1 ... linking ... done.
Loading package template-haskell ... linking ... done.
Loading package ghc-7.4.1 ... linking ... done.
Ok, modules loaded: Test.
Prelude Test> typecheck [] "Test.hs"
Loading package transformers-0.3.0.0 ... linking ... done.
Loading package mtl-2.1.1 ... linking ... done.
Prelude Test> 

Таким образом, хитрость заключается в том, чтобы передать открытые пакеты в dynflags аргумент setSessionDynFlags, Посмотрите модуль DynFlags для некоторой документации.

Другие вопросы по тегам