Skip to content

Commit b3f4901

Browse files
authored
Improve README
* Fix now-incorrect statement about the folder from which to run example.hs * Include examples early and often, don't make readers click through to example.hs * Reword the feature list * List known limitations
1 parent 33332af commit b3f4901

File tree

1 file changed

+68
-12
lines changed

1 file changed

+68
-12
lines changed

README.md

+68-12
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,75 @@
33
[![Build Status](https://travis-ci.com/haskell-hint/hint.svg?branch=master)](https://travis-ci.com/haskell-hint/hint)
44
[![Hackage](https://img.shields.io/hackage/v/hint.svg)](https://hackage.haskell.org/package/hint)
55

6-
This library defines an Interpreter monad. It allows to load Haskell
7-
modules, browse them, type-check and evaluate strings with Haskell
8-
expressions and even coerce them into values. The library is thread-safe
9-
and type-safe (even the coercion of expressions to values).
6+
This library defines an Interpreter monad within which you can interpret
7+
strings like `"[1,2] ++ [3]"` into values like `[1,2,3]`. You can easily
8+
exchange data between your compiled program and your interpreted program, as
9+
long as the data has a `Typeable` instance.
1010

11-
It is, essentially, a huge subset of the GHC API wrapped in a simpler
12-
API.
11+
You can choose which modules should be in scope while evaluating these
12+
expressions, you can browse the contents of those modules, and you can ask for
13+
the type of the identifiers you're browsing.
1314

14-
Compatibility is kept with the three last major GHC releases. For
15-
example, if the current version is GHC 8.6, Hint will work on 8.6, 8.4
16-
and 8.2.
15+
It is, essentially, a huge subset of the GHC API wrapped in a simpler API.
1716

18-
### Example
17+
## Limitations
1918

20-
Check [example.hs](examples/example.hs) to see a simple but
21-
comprehensive example (it must be run from the `examples` directory).
19+
It is possible to run the interpreter inside a thread, but you can't run two
20+
instances of the interpreter simlutaneously.
21+
22+
GHC must be installed on the system on which the compiled executable is running.
23+
24+
Compatibility is kept with the three last major GHC releases. For example, if
25+
the current version is GHC 8.6, `hint` will work on 8.6, 8.4 and 8.2.
26+
27+
## Example
28+
29+
{-# LANGUAGE LambdaCase, ScopedTypeVariables, TypeApplications #-}
30+
import Control.Exception (throwIO)
31+
import Control.Monad.Trans.Class (lift)
32+
import Control.Monad.Trans.Writer (execWriterT, tell)
33+
import Data.Foldable (for_)
34+
import Data.Typeable (Typeable)
35+
import qualified Language.Haskell.Interpreter as Hint
36+
37+
-- |
38+
-- Interpret expressions into values:
39+
--
40+
-- >>> eval @[Int] "[1,2] ++ [3]"
41+
-- [1,2,3]
42+
--
43+
-- Send values from your compiled program to your interpreted program by
44+
-- interpreting a function:
45+
--
46+
-- >>> f <- eval @(Int -> [Int]) "\\x -> [1..x]"
47+
-- >>> f 5
48+
-- [1,2,3,4,5]
49+
eval :: forall t. Typeable t
50+
=> String -> IO t
51+
eval s = runInterpreter $ do
52+
Hint.setImports ["Prelude"]
53+
Hint.interpret s (Hint.as :: t)
54+
55+
-- |
56+
-- >>> :{
57+
-- do contents <- browse "Prelude"
58+
-- for_ contents $ \(identifier, tp) -> do
59+
-- when ("put" `isPrefixOf` identifier) $ do
60+
-- putStrLn $ identifier ++ " :: " ++ tp
61+
-- :}
62+
-- putChar :: Char -> IO ()
63+
-- putStr :: String -> IO ()
64+
-- putStrLn :: String -> IO ()
65+
browse :: Hint.ModuleName -> IO [(String, String)]
66+
browse moduleName = runInterpreter $ do
67+
Hint.setImports ["Prelude", "Data.Typeable", moduleName]
68+
exports <- Hint.getModuleExports moduleName
69+
execWriterT $ do
70+
for_ exports $ \case
71+
Hint.Fun identifier -> do
72+
tp <- lift $ Hint.typeOf identifier
73+
tell [(identifier, tp)]
74+
_ -> pure () -- skip datatypes and typeclasses
75+
76+
Check [example.hs](examples/example.hs) for a longer example (it must be run
77+
from hint's base directory).

0 commit comments

Comments
 (0)