2

改めてお詫び申し上げます。ここでHaskellの実装に関して以前にこの質問をしましたが、これがどのように機能するかについて頭を悩ませることはまだ困難です。また、ミニマリズムプログラミング言語の概念は絶対に魅力的であり、それから逃れることはできません...とにかく、これは関数型プログラミングの美しさについて懐かしい場所ではありません。

それで!難解プログラミング言語に関するウェブサイトを見つけ、Iotaを発見しました。Iotaは間違いなく最小の関数型言語です。詳細については、「Iota and Jot:最も単純な言語?」を参照してください。スキームでの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実装と同等のエレガンスを試してみると、「悪いproc」が吐き出されてしまいます。誰かがRubyがこのように動作している理由と、これをより適切に実装する方法を理解するのを手伝ってもらえますか?これを機能させようとしている間、私はS、、、を読みやすくするためKBASIS分離しました。

下部に2つのテストを含めました。最初はIBASIS[BASIS])を返す必要がありますが、代わりに、と同じ結果を生成しないprocを返しますI。2番目のテストはを返すはず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)
4

2 に答える 2

4

9行目では、を呼び出していますがi[i]i引数を取りません。によって返されるラムダのみが引数を取りますi。したがって、引数なしで呼び出してから、引数として呼び出した結果を呼び出す必要がありiます。iii[][i]

于 2012-08-31T16:37:08.133 に答える
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
于 2012-08-31T18:15:29.843 に答える