让简单的Haskell HsLua示例运行起来。

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 代码甚至都不能编译),但它就像下面这样(与维基页面上相同):

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 调用示例?

编辑

好的,我将返回值的类型从之前的 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

这是 configfile.lua -

function getuserpwd (site)
  return "boss"
end

运行时错误消息如下 -

**** Exception: user error (attempt to call a nil value)

原文链接 https://stackoverflow.com/questions/7402423

点赞
stackoverflow用户507883
stackoverflow用户507883

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

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) --在没有Haskell扩展的情况下调用函数
  print_table l
  Lua.close l

结果发现,HsLua实现非常简单,并且没有适合Lua表的Haskell绑定。

2011-09-13 15:08:56
stackoverflow用户2355077
stackoverflow用户2355077

另外,dostring + dofile 工具:

https://github.com/ajnsit/luautils

http://hackage.haskell.org/package/luautils

luaDoString :: Lua.LuaState -> String -> IO Int
result <- luaDoString l "return 2^3"
2013-05-06 14:37:50