Skip to content

Commit

Permalink
added first prototype, used hint to download and execute code
Browse files Browse the repository at this point in the history
updated README
  • Loading branch information
Shae Erisson committed May 19, 2012
1 parent d127cd5 commit 7f1e308
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 1 deletion.
11 changes: 10 additions & 1 deletion README.md
@@ -1,4 +1,13 @@
ghclive
=======

Google Summer of Code 2012 project, GHCi for the web
Google Summer of Code 2012 project, GHCi for the web

Prototypes
----------
The prototypes subdirectory contains several quick hacks demonstrating various concepts.

### Using hint to download and execute code from the web ###

prototypes/hintdownload/ is the example.hs from http://code.haskell.org/hint/devel/examples/
modified to download and execute Demo.main from http://www.scannedinavian.com/~shae/Demo.hs
7 changes: 7 additions & 0 deletions prototypes/hintdownloadexecute/SomeModule.hs
@@ -0,0 +1,7 @@
module SomeModule(g, h) where

f = head

g = f [f]

h = f
78 changes: 78 additions & 0 deletions prototypes/hintdownloadexecute/example.hs
@@ -0,0 +1,78 @@
{- this code stolen from http://code.haskell.org/hint/devel/examples/ -}
import Control.Monad
import Language.Haskell.Interpreter
import Network.Curl.Download
import qualified Data.ByteString as BS

url = "http://www.scannedinavian.com/~shae/Demo.hs"

main :: IO ()
main = do doc <- openURI url
case doc of
Left err -> putStrLn err
Right r -> BS.writeFile "Demo.hs" r
r <- runInterpreter testHint
case r of
Left err -> printInterpreterError err
Right () -> putStrLn "that's all folks"

-- observe that Interpreter () is an alias for InterpreterT IO ()
testHint :: Interpreter ()
testHint =
do

say "Load SomeModule.hs"
loadModules ["SomeModule.hs","Demo.hs"]
--
say "Put the Prelude, Data.Map and *SomeModule in scope"
say "Data.Map is qualified as M!"
setTopLevelModules ["SomeModule", "Main"]
setImportsQ [("Prelude", Nothing), ("Data.Map", Just "M")]
--
say "Now we can query the type of an expression"
let expr1 = "M.singleton (f, g, h, 42)"
say $ "e.g. typeOf " ++ expr1
say =<< typeOf expr1
--
say $ "Observe that f, g and h are defined in SomeModule.hs, " ++
"but f is not exported. Let's check it..."
exports <- getModuleExports "SomeModule"
say (show exports)
--
say "We can also evaluate an expression; the result will be a string"
let expr2 = "length $ concat [[f,g],[h]]"
say $ concat ["e.g. eval ", show expr1]
a <- eval expr2
say (show a)
--
say "Or we can interpret it as a proper, say, int value!"
a_int <- interpret expr2 (as :: Int)
say (show a_int)
--
let greetz = "main"
say "Run the main that's loaded from Demo.hs"
greetinternet <- interpret greetz (as :: IO ())
liftIO greetinternet
--
say "This works for any monomorphic type, even for function types"
let expr3 = "\\(Just x) -> succ x"
say $ "e.g. we interpret " ++ expr3 ++
" with type Maybe Int -> Int and apply it on Just 7"
fun <- interpret expr3 (as :: Maybe Int -> Int)
say . show $ fun (Just 7)
--
say "And sometimes we can even use the type system to infer the expected type (eg Maybe Bool -> Bool)!"
bool_val <- (interpret expr3 infer `ap` (return $ Just False))
say (show $ not bool_val)
--
say "Here we evaluate an expression of type string, that when evaluated (again) leads to a string"
res <- interpret "head $ map show [\"Worked!\", \"Didn't work\"]" infer >>= flip interpret infer
say res


say :: String -> Interpreter ()
say = liftIO . putStrLn

printInterpreterError :: InterpreterError -> IO ()
printInterpreterError e = putStrLn $ "Ups... " ++ (show e)

0 comments on commit 7f1e308

Please sign in to comment.