1

このIF-THEN-ELSEラムダ計算コードを作成しました

(defvar IF-THEN-ELSE
    #'(lambda(con)
        #'(lambda(x)
            #'(lambda(y)
                #'(lambda(acc1)
                    #'(lambda (acc2)
                        (funcall (funcall (funcall (funcall con x) y) acc1) acc2))))))
)

(defun IF-THEN-ELSEOP(c x y a1 a2)
    (funcall (funcall (funcall (funcall (funcall IF-THEN-ELSE c) x) y) a1) a2)
)

そして、このGreater or Equal演算子

(defvar GEQ
    #'(lambda(p)
        #'(lambda(q)
              (funcall #'LEQOP q p)))
)

LEQOP は「Less or Equal」の機能であり、問​​題なく動作します。したがって、このように IF-THEN-ELSE を呼び出すと (「6」と「2」は教会番号です)

(if-then-elseop GEQ six two (print "THIS") (print "THAT"))

私が持っている出力として

"THIS" 
"THAT" 
"THIS"

私が渡している両方の関数が呼び出されています。出力「THIS」としてのみ取得するには、どうすれば回避できますか?

これは私が使用するすべての関数で発生します。再帰呼び出しで IF-THEN-ELSE を使用したいので、これは問題です。

どんな助けでもいただければ幸いです

ありがとう。

4

1 に答える 1

1

printステートメントを s でラップして渡すことlambdaは機能するはずですが、これが必要な理由について説明する価値があるかもしれません。

ラムダ計算を実装しています。定義上、微積分のすべての「もの」は高階関数です。あなたsixとあなたtwoが定義した他の教会の数字も高階関数です。

IF-THEN-ELSEラムダ抽象化です(「引数」も関数であるため、高階関数でもあります)。したがって、これは有効でした:

(if-then-elseop GEQ six two one two)

oneとは教会two番号です。そうすることで、普通の Lisp で行うことをラムダ計算で次のように表現できます。

(if (>= 6 2) 
  1 
  2)

しかし、あなたが目指していたのは次のことだったと思います:

(if (>= 6 2) 
  (print "this")
  (print "that"))

print(なぜいじることがあなたの運動の気を散らすかもしれないかについては後で詳しく説明します)

したがって、「本物」1には教会のエンコーディングoneがあり、これはあなたが定義したと思います。そうすれば、ラムダ抽象化に適用できますIF-THEN-ELSE-同じ方法で

(>= 6 2)

Lispの世界では TRUE と評価され、同じラムダ計算の実装、

((GEQ six) two)

TRUEのラムダ エンコーディングに評価されますが、これも高階関数としてエンコードされます。

(defvar TRUE #'(lambda (x) #'(lambda (y) x)))
(defvar FALSE #'(lambda (x) #'(lambda (y) y)))

したがって、覚えておくべき規則は、ラムダ計算で受け渡したり戻ったりするものはすべて関数であるということです。

 0 := λf.λx.x             
 1 := λf.λx.f x
 2 := λf.λx.f (f x)
 3 := λf.λx.f (f (f x))
 ... and so on

これが、あなたがした場合の理由です:

(if-then-elseop GEQ six two 
   #'(lambda () (print "THIS"))
   #'(lambda () (print "THAT")))

動作するはずです。(一種の、先読み)

(ただし、次の忠実な解釈に固執しIF-THEN-ELSEます:

(defvar IFTHENELSE 
  #'(lambda (p) 
    #'(lambda (a) 
      #'(lambda (b) (funcall (funcall p a) b)))))

あなたの状態はどこですかp... )

print補足として、ラムダ計算内で「何かを行う」他のコードを持ち込むことはあまり役に立たない可能性があることを指摘する価値があります-計算はIOを定義せず、ラムダ式の評価に制限されています。教会のエンコーディングは、数値をラムダ項としてエンコードする方法です。ラムダ項などの副作用を持つステートメントを表す簡単で意味のある方法はありません。機能しますが、学術的な演習としては、物事を評価して結果を返すことだけに固執するのが最善です.(print "hello")#'(lambda () (print "THIS"))

Lisp自体はどうですか?ifin lisp は関数ではないので、(if cond then-expr else-expr)期待どおりに動作します (つまり、実際に評価されるのはthen-exprorの 1 つだけです)。これは特殊な形式であるためです。独自に定義する場合は、マクロが必要になります(@wvxvw が正しく示唆しているように)。しかし、それは別のトピックです。else-expr

于 2012-11-30T16:25:27.550 に答える