Haskell Wiki上的HsLua示例已被破坏(dostring和dofile未定义).看起来自从编写示例以来API已经发生了变化.
但是,我一直在尝试修改示例以匹配当前的API,但没有取得多大成功.这里有一个程序,应该真正的工作!
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
Run Code Online (Sandbox Code Playgroud)
但是,这甚至没有编译,给我这个奇怪的错误信息 -
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";
.... }
Run Code Online (Sandbox Code Playgroud)
虽然文件的内容configfile.lua
可能无关紧要(因为haskell代码甚至没有编译),但它如下(与维基页面相同) -
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
Run Code Online (Sandbox Code Playgroud)
有人可以给我一个Haskell-> Lua和Lua-> Haskell调用的工作示例吗?
编辑
好吧,我将返回值的类型更改为String(来自早期的String数组),该程序确实编译了!但是它现在在运行时失败了.这是修改后的程序 -
main = do
l <- Lua.newstate
Lua.openlibs l
Lua.loadfile l "configfile.lua"
Lua.callfunc l "getuserpwd" "mail.google.com" >>= putStrLn
Lua.close l
Run Code Online (Sandbox Code Playgroud)
这是configfile.lua -
function getuserpwd (site)
return "boss"
end
Run Code Online (Sandbox Code Playgroud)
并且运行时错误消息如下 -
**** Exception: user error (attempt to call a nil value)
Run Code Online (Sandbox Code Playgroud)
您必须在调用任何函数之前执行加载的Lua块:
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
Run Code Online (Sandbox Code Playgroud)
方法dofile是loadfile和call的包装器,我不知道删除它的原因.
编辑. 此代码调用返回表并迭代它的函数.它基于这个遍历示例.我不知道如何通过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
Run Code Online (Sandbox Code Playgroud)
事实证明,HsLua实现是一个非常简单的包装器,并且Lua表没有合适的Haskell绑定.