haskell - 让一个简单的 Haskell HsLua 示例工作

标签 haskell lua

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

然而,这甚至没有编译,给了我这个奇怪的错误信息 -
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";
             .... }

而文件的内容configfile.lua可能没关系(因为haskell代码甚至没有编译),它如下(与wiki页面相同) -
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

有人可以为我提供 Haskell->Lua 和 Lua->Haskell 调用的工作示例吗?

编辑

好的,我将返回值的类型更改为字符串(从早期的字符串数组),并且该程序确实编译了!但是它现在在运行时失败。这是修改后的程序 -
main = do
    l <- Lua.newstate
    Lua.openlibs l
    Lua.loadfile l "configfile.lua"
    Lua.callfunc l "getuserpwd" "mail.google.com" >>= putStrLn
    Lua.close l

这是 configfile.lua -
function getuserpwd (site)
  return "boss"
end

并且运行时错误信息如下——
**** Exception: user error (attempt to call a nil value)

最佳答案

您必须在调用任何函数之前执行加载的 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

方法 dofile 是 loadfile 和 call 的包装器,我不知道删除它的原因。

编辑。
此代码调用返回表并对其进行迭代的函数。它基于 this遍历示例。我不知道如何通过 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

事实证明,HsLua 实现是一个非常简单的包装器,并且没有适合 Lua 表的 Haskell 绑定(bind)。

关于haskell - 让一个简单的 Haskell HsLua 示例工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7402423/

相关文章:

linux - 如何在ubuntu上更新lua包?

lua - 如何转储所有_G表内容

haskell - Haskell 中是否可以执行嵌套 if 语句?

haskell - 如何完全中止 Haskell 运行时?

haskell - Cabal安装标准内存不足

string - Lua中阿拉伯字母的长度

c - 使用lua的lightuserdata注册定时器回调

Haskell IO 执行顺序

haskell - 计数枚举值的频率

lua - GA 种群中的随机顺序在 Lua 中无法正常工作