Оценка Операторов/Выражений Haskell с помощью GHC API

Для инструмента я пишу (http://hackage.haskell.org/package/explore), мне нужен способ прочитать определения функции haskell во времени выполнения, применить их к значениям от моего инструмента и получить результаты их приложения.

Кто-либо может дать мне очень простой пример с помощью GHC (6.10.4 или 6.12.1) API?

определение функции в качестве примера, которое будет считано из файла во времени выполнения:

f x = 10**(4/1102*x - 1)

ожидаемая программа производится

--mapM_ print $ map f [428, 410, 389]
3.577165388142748
3.077536885227335
2.5821307011665815

!! ОБНОВЛЕНИЕ!!
Я отправил быстрый ответ, но он создает объектный файл в каталоге выполнения, любые подсказки, чтобы избежать этого и избежать всего файла, IO приветствуется. Я хочу также видеть версию, которая делает все в памяти: пользователь предоставляет функциональное определение в GUI, например, и компиляции / оценка не создает объектных файлов.

19
задан Cetin Sert 16 March 2010 в 00:56
поделиться

3 ответа

Используйте подсказку . Это похожая на GHCi оболочка для GHC API, которую не очень сложно использовать.

Если вам нужен пример его использования, я использовал его в своем проекте «Йогурт» .

6
ответ дан 30 November 2019 в 05:06
поделиться

адаптировано из: http://www.bluishcoder.co.nz/2008/11/dynamic-compilation-and-loading-of.html

f.hs:

module Func (Func.f) where

f :: Double -> Double
f x = 10**(4/1102*x - 1)

main.hs:

import GHC
import GHC.Paths
import DynFlags
import Unsafe.Coerce

import Control.Monad

main :: IO ()
main =
    defaultErrorHandler defaultDynFlags $ do
      func <- runGhc (Just libdir) $ do
        dflags <- getSessionDynFlags
        setSessionDynFlags dflags
        target <- guessTarget "f.hs" Nothing
        addTarget target
        r <- load LoadAllTargets
        case r of
          Failed -> error "Compilation failed"
          Succeeded -> do
            m <- findModule (mkModuleName "Func") Nothing
            setContext [] [m]
            value <- compileExpr ("Func.f")
            do let value' = (unsafeCoerce value) :: Double -> Double
               return value'
      let f = func
      mapM_ print $ map f [428, 410, 389]
      return ()
5
ответ дан 30 November 2019 в 05:06
поделиться

Хорошая работа, запуск API. Могу немного рассказать о том, как работает генератор кода.

GHC использует системный ассемблер для создания файла .o. Если нет возможности заставить GHC убирать за собой, вам следует отправить запрос функции к API, используя трекер ошибок по адресу http://hackage.haskell.org/trac/ghc/newticket ? type = feature + request . Для того, чтобы подать заявку, вам необходимо зарегистрировать учетную запись.

Используя стандартный генератор кода, вы не сможете полностью избежать файлового ввода-вывода только потому, что GHC делегирует работу по созданию перемещаемого объектного кода ассемблеру. Существует экспериментальная серверная часть, основанная на LLVM, которая может делать все в памяти, но я был бы удивлен, если бы она была доступна в версиях, предшествующих 6.13. Однако, возможно, стоит спросить о списке разработчиков GHC.

4
ответ дан 30 November 2019 в 05:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: