The HsLua examples on the Haskell Wiki are broken (dostring and dofile are not defined). Looks like the API has changed since the examples were written.
However I have been trying to modify the examples to match the current API and not getting much success. Here's 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 doesn't even compile, giving me this 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 content of the file configfile.lua
probably doesn't matter (because the haskell code doesn't even compile), it is as 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
Could someone please provide me with a working example of Haskell->Lua and Lua->Haskell calls?
Edit
Okay I changed the type of the return value to a String (from the earlier array of String), and that program does compile! However it now fails 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's configfile.lua -
function getuserpwd (site)
return "bo开发者_高级运维ss"
end
And the runtime error message is as follows -
**** Exception: user error (attempt to call a nil value)
You have to execute loaded Lua chunk prior to calling any functions:
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
Method dofile was a wrapper for loadfile and call, I don't know reasons for removing it.
Edit. This code calls function that returns table and iterates over it. It is based on this traversal example. I am not sure how to do it via 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 HsLua implementation is a very simple wrapper and there are no suitable Haskell bindings for Lua tables.
additionaly
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"
精彩评论