如何在lua中线程、管道或组合函数?

问题描述 投票:0回答:1

如果我想将一个值传递给 foo()、将其返回值传递给 bar()、将其返回值传递给 baz() 等,在 lua 中该怎么办?

附件 A(伪代码):

backwards(code(reading(like(not(do(I))))))

图表 B(伪代码):

local all = foo(...)
local this = bar(all)
local variables = baz(this)
local obscure_a_simple_idea = quux(variables)

在 F# 中此代码(

let numbers = [0..100]
let evenNumbers = List.filter isEven numbers
let doubledNumbers = List.map double evenNumbers
List.iter printNumber doubledNumbers

可以这样重写:

[0..100]
|> List.filter isEven
|> List.map double
|> List.iter printNumber

在 clojure 中这段代码(source

(defn calculate []
   (reduce + (map #(* % %) (filter odd? (range 10)))))

可以这样写

(defn calculate* []
   (->> (range 10)
        (filter odd? ,,,)
        (map #(* % %) ,,,)
        (reduce + ,,,)))

我知道茴香有线程宏。我想知道:我能用lua做什么?我错过了语言功能吗?有什么我不知道的众所周知的成语吗?我是否被迫在证据 A、证据 B 或迁移到茴香之间进行选择?

lua functional-programming code-structure
1个回答
0
投票

好消息:Lua 具有一流的功能,因此几乎所有这些都可以在普通 Lua 中实现! (不过,它可能更冗长和/或效率低下。)

让我们从函数组合开始:

function compose(f, g)
    return function(...)
        return f(g(...))
    end
end

这仍然是“错误”的顺序:

f(g(x))
相当于
compose(f, g)(x)

让我们在可变参数上写一个左折叠:

function foldl(f, acc, ...)
    if select("#", ...) == 0 then
        return acc
    end
    local l = ...
    return foldl(f, f(acc, l, select(2, ...))
end

我们还定义恒等函数:

function id(...) return ... end

现在让我们来处理附件 A:

function compose_multiple(...) return foldl(compose, id, ...) end
compose_multiple(backwards, code, reading, like, dont)(I)

这仍然是倒着读。如果您不想这样做,只需定义一个相反的组合即可:

function compose_flipped(inner, outer)
    return function(...)
        return outer(inner(...))
    end
end

(您也可以将其定义为

compose_flipped = compose(compose, function(x, y) return y, x end
;))

现在:

function chain(...) return foldl(compose_flipped, id, ...) end
chain(dont, like, reading, code, backwards)(I)

由于链接只是与另一个顺序的组合,它返回一个函数,因此参数仍然在右侧。如果您对此不满意,您可以自己编写一个接受参数并执行调用的函数,类似于 F# / Clojure 必须提供的线程:

function chaincall(arg, ...) return chain(...)(arg) end

现在您的附件 A 变为

chaincall(I, dont, like, reading, code, backwards)

© www.soinside.com 2019 - 2024. All rights reserved.