Use the package hint
we can define eval
very easily, following is an example as self-contained script (you still need nix to run it)
#!/usr/bin/env nix-shell
#! nix-shell -p "haskellPackages.ghcWithPackages (p: with p; [hint])"
#! nix-shell -i "ghci -ignore-dot-ghci -fdefer-type-errors -XTypeApplications"
{-# LANGUAGE ScopedTypeVariables, TypeApplications, PartialTypeSignatures #-}
import Data.Typeable (Typeable)
import qualified Language.Haskell.Interpreter as Hint
-- DOC: https://www.stackage.org/lts-18.18/package/hint-0.9.0.4
eval :: forall t. Typeable t => String -> IO t
eval s = do
mr <- Hint.runInterpreter $ do
Hint.setImports ["Prelude"]
Hint.interpret s (Hint.as :: t)
case mr of
Left err -> error (show err)
Right r -> pure r
-- * Interpret expressions into values:
e1 = eval @Int "1 + 1 :: Int"
e2 = eval @String "\"hello eval\""
-- * Send values from your compiled program to your interpreted program by interpreting a function:
e3 = do
f <- eval @(Int -> [Int]) "\\x -> [1..x]"
pure (f 5)