Для инструмента я пишу (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, например, и компиляции / оценка не создает объектных файлов.
Используйте подсказку . Это похожая на GHCi оболочка для GHC API, которую не очень сложно использовать.
Если вам нужен пример его использования, я использовал его в своем проекте «Йогурт» .
адаптировано из: 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 ()
Хорошая работа, запуск API. Могу немного рассказать о том, как работает генератор кода.
GHC использует системный ассемблер для создания файла .o. Если нет возможности заставить GHC убирать за собой, вам следует отправить запрос функции к API, используя трекер ошибок по адресу http://hackage.haskell.org/trac/ghc/newticket ? type = feature + request . Для того, чтобы подать заявку, вам необходимо зарегистрировать учетную запись.
Используя стандартный генератор кода, вы не сможете полностью избежать файлового ввода-вывода только потому, что GHC делегирует работу по созданию перемещаемого объектного кода ассемблеру. Существует экспериментальная серверная часть, основанная на LLVM, которая может делать все в памяти, но я был бы удивлен, если бы она была доступна в версиях, предшествующих 6.13. Однако, возможно, стоит спросить о списке разработчиков GHC.