lua 中的柯里化操作

Currying operations in lua

这个问题对这个问题有一定的借鉴意义。以下代码工作正常。

local function _implies(a, b)
      if a == 1 and b == 0 then return 0 
        else return 1 end
    end
    
    local my_right = {
        __mul = function(self, b)
            return _implies(self.a, b)
        end
      }
      
      local _mt =  {
        __mul = function(a)
            return setmetatable({a=a}, my_right)
        end
    }
    
    local my_left={}
    setmetatable(my_left,_mt)
    imp = my_left
    local names={}
    
    
    for i = 0,1 do
       for j=0,1 do
         names.i=i;names.j=j
       print(i, j, names.i *imp* names.j)
      
       end
    end

以下代码与上述代码类似。它用于 逻辑和 。我想问的问题是: and_leftand_right 在这种情况下是否也需要?他们是必需的,因为 implies 不是可交换的吗?换句话说,是否可以使代码在定义 logand?

时更有效
    local function _and(a, b)
          if a == 1 and b == 1 then return 1 
            else return 0 end
    end
    
    local right_and = {
        __mul = function(self, b)
            return _and(self.a, b)
        end
      }
      
      local and_mt =  {
        __mul = function(a)
            return setmetatable({a=a}, right_and)
        end
    }
    
    local and_left={}
    setmetatable(and_left,and_mt)
   log_and = and_left
    local names={}
    
    
    for i = 0,1 do
       for j=0,1 do
 names.i=i;names.j=j
       print(i, j, names.i *log_and* names.j)
      
       end
end

注意:我知道按位运算符 & 在那里,但出于某些原因,我不想使用它。

Are both and_left and and_right are required

引入它们是因为涉及两个语义不同的乘法。

但是代码可以优化
下面的版本不会在每次乘法时创建一个新的 table。
它还只使用一个 metatable 而不是两个。

do
   local function _implies(a, b)
      if a == 1 and b == 0 then
         return 0
      else
         return 1
      end
   end

   local temp, imp = {}, {}
   local _mt =  {
      __mul = function(a, b)
         if b == imp then
            temp[1] = a
            return temp
         elseif a == temp then
            return _implies(temp[1], b)
         end
      end
   }
   setmetatable(temp, _mt)
   setmetatable(imp, _mt)
   _G.imp = imp
end

local names={}
for i = 0, 1 do
   for j = 0, 1 do
      names.i=i
      names.j=j
      print(i, j, names.i *imp* names.j)
   end
end