消除这个Lua monad模仿中的递归

时间:2015-08-13 18:49:14

标签: haskell recursion lua parsec

我试图在Lua中粗略地复制Parsec,并且我在绑定函数是递归的时候遇到了一些麻烦生成递归{{1} }第

runParser

我使用自定义制作ADT的系统,因此返回值上的function Parser:bind(f) return new(function(s) local result = self.runParser(s) if result.cons() == Result.Success then return f(result.get()).runParser(result.get(2)) else return result end end) end cons()函数。等效的Haskell代码就是这样的。

get()

m >>= f = Parser $ \s -> case result of Success a cs -> runParser (f a) cs _ -> result where result = runParser m s 构造函数(Lua中的Parser函数)的参数是new函数。因此,在runParser内以非尾递归方式调用不同的runParser会生成非常深的调用堆栈,从而导致堆栈溢出。有关删除递归或将其转换为尾递归的提示吗?

1 个答案:

答案 0 :(得分:1)

延续传递让这很容易解决。

function Parser:bind(f)
    return new(function(s, cont)
        return self.runParser(s, function(result)
            if result.cons() == Result.Success then
                return f(result.get()).runParser(result.get(2), cont)
            else
                return cont(result)
            end
        end)
    end)
end

这样,它的尾巴一直调低!不可否认,f可能会自行溢出,但这可能是用户方面编程错误的情况,因为f不应该非常深入。