Getting a simple Haskell HsLua example to work

HsLua examples on the Haskell Wiki are broken (dostring and dofile are undefined). It looks like the API has changed since the examples were written.

However, I tried to modify the examples to fit the current API and not be very successful. Here is a program that should really work!

main = do l <- Lua.newstate Lua.openlibs l Lua.loadfile l "configfile.lua" [name,pwd] <- Lua.callfunc l "getuserpwd" "mail.google.com" putStrLn name Lua.close l 

However, this does not even compile, since to me this is a strange error message -

 No instance for (Lua.StackValue [String]) arising from a use of `Lua.callfunc' Possible fix: add an instance declaration for (Lua.StackValue [String]) In a stmt of a 'do' expression: [name, pwd] <- Lua.callfunc l "getuserpwd" "mail.google.com" In the expression: do { l <- Lua.newstate; Lua.openlibs l; Lua.loadfile l "configfile.lua"; [name, pwd] <- Lua.callfunc l "getuserpwd" "mail.google.com"; .... } In an equation for `main': main = do { l <- Lua.newstate; Lua.openlibs l; Lua.loadfile l "configfile.lua"; .... } 

While the contents of the configfile.lua file probably doesn't matter (since the haskell code doesn't even compile), it's like below (same as on the wiki page) -

 function getuserpwd (site) local cookies = { ["www.ibm.com"] = {"joe", "secret"} , ["www.sun.com"] = {"hoe", "another secret"} } if cookies[site] then return cookies[site] elseif site:match("[.]google[.]com$") then return {"boss", "boss"} else return { os.getenv("USER") or "God" , os.getenv("PWD") or "dontdisturb" } end end 

Can someone please provide me with a working example of Haskell-> Lua and Lua-> Haskell?

Edit

Well, I changed the return type to String (from an earlier array of String), and this program compiles! However, now it does not work at runtime. Here's the modified program -

 main = do l <- Lua.newstate Lua.openlibs l Lua.loadfile l "configfile.lua" Lua.callfunc l "getuserpwd" "mail.google.com" >>= putStrLn Lua.close l 

And here is configfile.lua -

 function getuserpwd (site) return "boss" end 

And the runtime error message looks like this:

 **** Exception: user error (attempt to call a nil value) 
+4
source share
2 answers

Before calling any functions, you must execute the loaded Lua block:

 main = do l <- Lua.newstate Lua.openlibs l Lua.loadfile l "configfile.lua" Lua.call l 0 0 Lua.callfunc l "getuserpwd" "mail.google.com" >>= putStrLn Lua.close l 

The dofile method was a wrapper for the download and call file, I don’t know the reasons for deleting it.

Edit This code calls a function that returns a table and iterates over it. It is based on this workaround example. I am not sure how to do this through callfunc.

 import qualified Scripting.Lua as Lua import Control.Monad.Loops import Data.Maybe print_table l = do Lua.pushnil l whileM_ (Lua.next l 1) (Lua.tostring l (-1) >>= putStrLn >> Lua.pop l 1) main = do l <- Lua.newstate Lua.openlibs l Lua.loadfile l "configfile.lua" Lua.call l 0 0 Lua.getglobal l "getuserpwd" Lua.pushstring l "mail.google.com" Lua.call l 1 (-1) -- calls function without Haskell extensions print_table l Lua.close l 

It turns out that the HsLua implementation is a very simple wrapper, and there are no suitable Haskell bindings for Lua tables.

+4
source

additional

dostring + dofile utils:
https://github.com/ajnsit/luautils
http://hackage.haskell.org/package/luautils

 luaDoString :: Lua.LuaState -> String -> IO Int result <- luaDoString l "return 2^3" 
0
source

All Articles