【问题标题】:Ruby and Lambda calculusRuby 和 Lambda 演算
【发布时间】:2013-08-12 21:58:13
【问题描述】:

我正在尝试使用 procs 和 ruby​​ 来理解 lambda 演算。这是一些代码:

puts -> x { -> y {x.call(y) } }
# => #<Proc:0x2a3beb0@C:/first-ruby.rb:1 (lambda)>

puts -> x { x + 2}.call(1)
# => 3

在上面的例子中-&gt; 是什么意思? call 方法是否将值传递给调用者,所以在第一个示例中,值y 被传递给y,而在第二个示例中,1 被传递给x?在第二个例子中,为什么1 被评估为x

【问题讨论】:

  • 您想了解 Ruby 还是 Lambda 微积分?你那个袋子里真的有很多猫。对于 Ruby 如何以各种方式处理 lambda,您得到了一些很好的答案。一个 lambda 是一个 Proc。来自内核文档“等效于 Proc.new,除了生成的 Proc 对象检查调用时传递的参数数量。”所以 Kernel 具有 lambda 函数或方法,但您可以通过查看具有 lambda 的 Proc 来了解更多信息?并检查 Proc 的类型,其中对于常规 Proc 对象会忽略额外参数,但对于 lambdas 可能会引发错误。
  • 不幸的是 -> 函数在 Ruby 中的文档很少,所以我们必须依靠 Ruby 社区来找到它的用法。我不是计算机科学专业的人,但它的逻辑确实与en.wikipedia.org/wiki/Lambda_calculus 密切相关
  • 我确实找到了这个词。在 Ruby 中尝试“匿名 lambdas”

标签: ruby lambda lambda-calculus


【解决方案1】:

这是纯 lambda 表达式的快捷方式:

lmbd = -> arg{ something to do with arg } # With ->{} notation

lmbd = lambda { |arg| something to do with arg } # Standard notation

在您的第一个示例中,您使用 Proc(lambda) 对象调用 puts 方法,这就是您在输出中看到 #&lt;Proc:0x2a3beb0@C:/first-ruby.rb:1 (lambda)&gt; 的原因。

在第二个示例中,您使用 lmbd.call(1) 方法调用 puts,即 puts 输出 lambda 计算的结果。

所以,如果你有 lmbd 变量是 lambda 对象,你可以像任何参数一样传递它,然后通过调用 lmbd.call() 得到它的结果:

lmbd = -> greeting{ puts "#{greeting}, lambda-expression!" }

def say_hello l, text
    l.call(text)
end

say_hello lmbd, "Aloha" # => Aloha, lambda-expression!

【讨论】:

    【解决方案2】:

    在上面的例子中-&gt; 是什么意思?

    -&gt; 是 lambda 文字语法的一部分,就像 ' 是字符串文字语法的一部分。

    .call 方法是否只是将值传递给调用者,

    call 方法是调用(或执行)lambda 的方法。 call 方法的参数绑定到 lambda 的参数。

    所以在第一个示例中,值y 被传递给y,在第二个示例中,1 被传递给x

    不,在第一个示例中,y 被传递给外部 lambda 并绑定到其 x 参数。在第二个示例中,1 被传递给 lambda 并绑定到其 x 参数。

    在第二个例子中,为什么1 被评估为x

    1 不会评估为 x1 是一个立即数,在 Ruby 中,立即数总是对自己求值。 1总是评估为 1从不评估为 x 或其他任何值。

    【讨论】:

      【解决方案3】:

      让我们使用 Ruby lambda 定义一个函数。

      def plus_two # no args here
        ->(x) {x + 2} # args go here
      end
      
      # assign a value
      x = 1
      
      # call it
      plus_two.call(x)
      # => 3
      

      您的第一个示例有点复杂,但是使用这个想法您应该能够提出函数式方法。 我正在学习 Scala,函数式编程基于这些替换原则。

      尝试使用这些进行一些递归。 这就像调用函数的函数 n 次。 那么基本情况是什么?

      关于 Lambda 演算 https://github.com/mackorone/lambda/blob/master/intro.pdf

      尽量保持简单并展示步骤,而不是试图弄清楚一个班轮在做什么。是的,它们很好,但如果你看不懂,你就无法理解。

      这是我最近在做的事情:

      require 'date'
      
      num = DateTime.now.to_time.utc.to_datetime.ajd - 2451545.0
      @t = num / 36525.0
      
      # the terms in reverse order form for the array
      @l0_a = [1.0/-19880000.0,
               1.0/-152990.0,
               1.0/499310.0,
               0.0003032028,
               36000.76982779,
               280.4664567]
      
       # make an enumerator
       @l0_e = @l0_a.each
      
       # make a lambda to pass the enumerator to.
       def my_lambda
         ->(x) {x.reduce {|acc, el| acc * @t + el} % 360}
       end
      
       puts  my_lambda.call(@l0_e)
      

      这是使用枚举器方法的太阳平均经度公式,当然还有 lambda。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-16
        相关资源
        最近更新 更多