Y Combinator

なんかはやっているらしい。でも一週間遅れだから乗り遅れ気味。書き換えネタ。

Y = lambda do |x|
  lambda do |procedure|
    x.call( lambda { |arg| procedure.call(procedure).call(arg) } )
  end.call (
    lambda do |procedure|
      x.call( lambda { |arg| procedure.call(procedure).call(arg) } )
    end
    )
end

fact = Y.call(
  lambda do |func_arg|
    lambda do |n|
      return 1 if n == 0
      n * func_arg.call([n - 1])
    end
  end
  )

Y Combinatorのはじめの

  lambda do |procedure|
    x.call( lambda { |arg| procedure.call(procedure).call(arg) } )
  end

は引数

  end.call (
    lambda do |procedure|
      x.call( lambda { |arg| procedure.call(procedure).call(arg) } )
    end
    )

を保存するために存在するので、最初の一回しか呼ばれない。

あと、

自分にはどうしても

  Y.call(F) == F.call(Y.call(F))

が理解できないorz。Yの引数xとFがごっちゃになるけど、考えてみると、

    lambda do |procedure|
      x.call( lambda { |arg| procedure.call(procedure).call(arg) } )
    end

のprocedureが

    lambda do |procedure|
      x.call( lambda { |arg| procedure.call(procedure).call(arg) } )
    end

だから、

lambda { |arg| procedure.call(procedure).call(arg) }

Y.call(F)

にあたり、

    x.call( lambda { |arg| procedure.call(procedure).call(arg) } )

F.call(Y.call(F))

になるから?なのか?