在ruby中实现iota

时间:2012-08-31 16:17:01

标签: ruby programming-languages functional-programming scheme combinators

我提前道歉再次提出这个问题。我之前就Haskell实现here提出了这个问题,但我仍然难以理解其工作原理。此外,我发现简约编程语言的概念绝对令人着迷,无法摆脱它......无论如何,这不是对函数式编程之美怀旧的地方。

原来如此!我找到了一个关于深奥编程语言的网站并发现了Iota。 Iota可以说是最小的功能语言。您可以在此处阅读更多相关信息:"Iota and Jot: the simplest languages?"以下是Scheme中Iota的参考实现:

(let iota ()
   (if (eq? #\* (read-char)) ((iota)(iota))
       (lambda (c) ((c (lambda (x) (lambda (y) (lambda (z) ((x z)(y z))))))
                    (lambda (x) (lambda (y) x))))))

但是,当我尝试使用与Ruby中的Scheme实现完全相同的东西时,最终会吐出一个“糟糕的过程”。任何人都可以帮助我理解为什么Ruby会以这种方式运行以及如何更好地实现它。在尝试将其付诸实践时,为了便于阅读,我将SKBASIS分开。

我在底部包含了两个测试。第一个应返回IBASIS[BASIS]),但它返回的proc不会产生与I相同的结果。第二个测试应返回K,但它会返回错误。

S = lambda {|f| lambda {|g| lambda {|x| f[x][g[x]] }}}
K = lambda {|x| lambda {|y| x }}
BASIS = lambda {|c| c[S][K] }

iota = lambda{|s|
   s = s.chars
   i = lambda {
      if s.next == '*'
         i[i]
      else
         BASIS
      end
   }
}

p BASIS[BASIS][1]         # => 1
p iota["*ii"][1]          # => #<Proc:0x000000010016b290>

p K[1][2]                 # => 1
p iota["*i*i*ii"][1][2]   # => line 3:in `[]': can't convert Proc into Integer (TypeError)

2 个答案:

答案 0 :(得分:4)

在第9行,您正在调用i[i],但i没有接受任何参数 - 只有i返回的lambda才会这样做。因此,您应该在没有参数的情况下调用i,然后调用以i为参数调用i的结果,即i[][i]

答案 1 :(得分:1)

感谢sepp2k,我想我已经弄明白了,对于任何有兴趣的人来说,这都是答案:

S = lambda {|f| lambda {|g| lambda {|x| f[x][g[x]] }}}
K = lambda {|x| lambda {|y| x }}
BASIS = lambda {|c| c[S][K] }

iota = lambda{|s|
   s = s.chars
   i = lambda {
      if s.next == '*'
         i[][i[]]
      else
         BASIS
      end
   }
   i[]
}

p BASIS[BASIS][1]          # => 1
p iota["*ii"][1]           # => 1

p K[1][2]                  # => 1
p iota["*i*i*ii"][1][2]    # => 1