Получение простого примера Haskell HsLua для работы - PullRequest
4 голосов
/ 13 сентября 2011

Примеры HsLua на Haskell Wiki не работают (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?

Edit

Хорошо, я изменил тип возвращаемого значения на 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)

Ответы [ 2 ]

5 голосов
/ 13 сентября 2011

Вы должны выполнить загруженный кусок 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) -- calls function without Haskell extensions
  print_table l
  Lua.close l

Оказывается, реализация HsLua - это очень простая оболочка, и нет подходящих привязок Haskell для таблиц Lua.

0 голосов
/ 06 мая 2013

дополнительно

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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...