コンピュータサイエンスでは、 「let」式は 関数 定義を制限された スコープ に関連付けます 。
「let」式は 数学 でも定義され、ブール条件を制限された範囲に関連付けます。
"let" 式は、 値に適用された ラムダ抽象化 と見なすことができます。数学においては、let 式は、変数のスコープを制限する 存在量指定子 内の式の 連言と見なすこともできます。
多くの関数型言語では、let式を用いて式のローカル定義を行い、別の式の定義に利用することができます。let式は、一部の関数型言語ではletまたは「let rec」という2つの形式で存在します。let recは、 固定小数点コンビネータを用いて 再帰を 実装する、単純なlet式の拡張版です 。
歴史 ダナ・スコット の LCF言語 [1] は、ラムダ計算が現代の関数型言語へと進化する過程の一段階でした。この言語はlet式を導入し、これはそれ以降のほとんどの関数型言語に見られるようになりました。
Scheme [ 2]、 ML 、そして最近では Haskell [3] などの言語は 、LCFからlet式を継承しています。
ALGOL や Pascal などの状態を持つ命令型言語は、 基本的にlet式を実装して、ブロック構造で関数のスコープを制限します。 [ 引用が必要 ]
密接に関連する「 where 」節とその再帰的な変種である「 where rec 」は、 ピーター・ランディン の 「式の機械的評価」 にすでに登場している 。 [4]
説明 「let」式は、別の式で使用する関数または値を定義します。多くの 関数型プログラミング言語で使用される構造であるだけでなく、数学のテキストでもよく使用される自然 言語構造 でもあります 。これは、where句の代替構文構造です。
Let式 where句 させて
a = 3 {\displaystyle a=3} そして
b = 4 {\displaystyle b=4} で
a 2 + b 2 {\displaystyle {\sqrt {a^{2}+b^{2}}}} a 2 + b 2 {\displaystyle {\sqrt {a^{2}+b^{2}}}} どこ
a = 3 {\displaystyle a=3} そして
b = 4 {\displaystyle b=4}
どちらの場合も、全体の構造は値が 5 である式です。if -then-else と同様に、式によって返される型は必ずしもブール値ではありません。
let式には主に4つの形式があります。
形状 そして 再帰的 定義 / 制約 説明 単純 いいえ いいえ 意味 単純な非再帰関数の定義。 再帰的 いいえ はい 意味 再帰関数の定義( Y コンビネータ を使用して実装)。 共通の はい はい 意味 相互再帰関数の定義。 数学 はい はい 制約 一般的なブール let 条件をサポートする数学的な定義。
関数型言語では、 let 式は式の中で呼び出すことができる関数を定義します。関数名のスコープはlet式の構造に限定されます。
数学において、let式は式に対する制約条件を定義します。この構文は、let式に局所的な存在量化変数の宣言をサポートする場合もあります。
用語、構文、意味論は言語によって異なります。Schemeでは 、 単純 形式では let 、再帰形式では let recが使用されます。MLでは、 letは 宣言ブロックの開始のみを示し、 funは 関数定義の開始を示します。Haskellでは、 letは 相互再帰になる可能性があり、コンパイラが必要な処理を判断します。
意味 ラムダ 抽象は、 名前のない関数を表します。これがラムダ抽象の定義における 矛盾の原因 です。しかし、ラムダ抽象は名前付きの関数を表すように構成することもできます。この形式では矛盾は解消されます。ラムダ項は、
( λ f . z ) ( λ x . y ) {\displaystyle (\lambda f.z)\ (\lambda x.y)} は、式 で 関数 を定義することと同等であり 、 let 式として記述することもできます。 f {\displaystyle f} f x = y {\displaystyle f\ x=y} z {\displaystyle z}
let f x = y in z {\displaystyle \operatorname {let} f\ x=y\operatorname {in} z} let 式は自然言語式として理解可能です。let 式は変数を値に置き換えることを表します。置換規則は、等号が置換としてどのような意味を持つかを記述します。
数学における定義 数学 において、 let 式 は式の連言として記述されます。関数型言語では、let式はスコープを制限するためにも用いられます。数学では、スコープは量指定子によって記述されます。let式は存在量指定子内の連言です。
( ∃ x E ∧ F ) ⟺ let x : E in F {\displaystyle (\exists xE\land F)\iff \operatorname {let} x:E\operatorname {in} F} ここで、 E と F はブール型です。
let式は 、 置換を別の式に適用することを可能にします。この置換は、限定されたスコープ内、つまり部分式に適用できます。let 式の自然な使い方は、限定されたスコープ( ラムダドロップ と呼ばれる)への適用です。以下の規則は、スコープの制限方法を定義します。
{ x ∉ FV ( E ) ∧ x ∈ FV ( F ) ⟹ let x : G in E F = E ( let x : G in F ) x ∈ FV ( E ) ∧ x ∉ FV ( F ) ⟹ let x : G in E F = ( let x : G in E ) F x ∉ FV ( E ) ∧ x ∉ FV ( F ) ⟹ let x : G in E F = E F {\displaystyle {\begin{cases}x\not \in \operatorname {FV} (E)\land x\in \operatorname {FV} (F)\implies \operatorname {let} x:G\operatorname {in} E\ F=E\ (\operatorname {let} x:G\operatorname {in} F)\\x\in \operatorname {FV} (E)\land x\not \in \operatorname {FV} (F)\implies \operatorname {let} x:G\operatorname {in} E\ F=(\operatorname {let} x:G\operatorname {in} E)\ F\\x\not \in \operatorname {FV} (E)\land x\not \in \operatorname {FV} (F)\implies \operatorname {let} x:G\operatorname {in} E\ F=E\ F\end{cases}}} ここで、 F はブール型ではありません。この定義から、関数型言語で使用されるlet式の標準的な定義を次のように導くことができます。
x ∉ FV ( y ) ⟹ ( let x : x = y in z ) = z [ x := y ] = ( λ x . z ) y {\displaystyle x\not \in \operatorname {FV} (y)\implies (\operatorname {let} x:x=y\operatorname {in} z)=z[x:=y]=(\lambda x.z)\ y} 簡潔にするために、存在変数を指定するマーカーは 、文脈から明らかな場合は式から省略されます。 x : {\displaystyle x:}
x ∉ FV ( y ) ⟹ ( let x = y in z ) = z [ x := y ] = ( λ x . z ) y {\displaystyle x\not \in \operatorname {FV} (y)\implies (\operatorname {let} x=y\operatorname {in} z)=z[x:=y]=(\lambda x.z)\ y}
導出 この結果を導くために、まず、
x ∉ FV ( L ) {\displaystyle x\not \in \operatorname {FV} (L)} それから
L ( let x : x = y in z ) ⟺ ( let x : x = y in L z ) ⟺ x = y ∧ L z {\displaystyle {\begin{aligned}L\ (\operatorname {let} x:x=y\operatorname {in} z)&\iff (\operatorname {let} x:x=y\operatorname {in} L\ z)\\&\iff x=y\land L\ z\end{aligned}}} 置換のルールを用いると、
⟺ x = y ∧ ( L z ) [ x := y ] ⟺ x = y ∧ ( L [ x := y ] z [ x := y ] ) ⟺ x = y ∧ L z [ x := y ] ⟹ L z [ x := y ] {\displaystyle {\begin{aligned}&\iff x=y\land (L\ z)[x:=y]\\&\iff x=y\land (L[x:=y]\ z[x:=y])\\&\iff x=y\land L\ z[x:=y]\\&\implies L\ z[x:=y]\end{aligned}}} したがって、すべてのL について 、
L let x : x = y in z ⟹ L z [ x := y ] {\displaystyle L\operatorname {let} x:x=y\operatorname {in} z\implies L\ z[x:=y]} ここ で K は新しい変数です。すると、 L X = ( X = K ) {\displaystyle L\ X=(X=K)}
( let x : x = y in z ) = K ⟹ z [ x := y ] = K {\displaystyle (\operatorname {let} x:x=y\operatorname {in} z)=K\implies z[x:=y]=K} それで、
let x : x = y in z = z [ x := y ] {\displaystyle \operatorname {let} x:x=y\operatorname {in} z=z[x:=y]} しかし、ベータ減少の数学的解釈から、
( λ x . z ) y = z [ x := y ] {\displaystyle (\lambda x.z)\ y=z[x:=y]} ここで、yが変数xの関数である場合、zにおけるxと同じではありません。アルファリネーミングが適用される場合があります。したがって、
x ∉ FV ( y ) {\displaystyle x\not \in \operatorname {FV} (y)} それで、
x ∉ FV ( y ) ⟹ let x : x = y in z = ( λ x . z ) y {\displaystyle x\not \in \operatorname {FV} (y)\implies \operatorname {let} x:x=y\operatorname {in} z=(\lambda x.z)\ y} この結果は関数型言語では省略形で表現され、意味は明確です。
x ∉ FV ( y ) ⟹ ( let x = y in z ) = z [ x := y ] = ( λ x . z ) y {\displaystyle x\not \in \operatorname {FV} (y)\implies (\operatorname {let} x=y\operatorname {in} z)=z[x:=y]=(\lambda x.z)\ y} ここで、変数 x は 、x を定義する方程式の一部であると同時に、存在量指定子の変数としても暗黙的に認識されます。
ブールからの持ち上げはなし Eが で定義されている場合、矛盾が生じます 。この場合、 E = ¬ {\displaystyle E=\neg }
x ∉ FV ( E ) ∧ x ∈ FV ( F ) ⟹ let x : G in E F = E ( let x : G in F ) {\displaystyle x\not \in \operatorname {FV} (E)\land x\in \operatorname {FV} (F)\implies \operatorname {let} x:G\operatorname {in} E\ F=E\ (\operatorname {let} x:G\operatorname {in} F)} となり、
let x : G in ¬ F = ¬ ( let x : G in F ) {\displaystyle \operatorname {let} x:G\operatorname {in} \neg F=\neg \ (\operatorname {let} x:G\operatorname {in} F)} そして使用して、
( ∃ x E ∧ F ) ⟺ let x : E in F {\displaystyle (\exists xE\land F)\iff \operatorname {let} x:E\operatorname {in} F} ( ∃ x G ∧ ¬ F ) = ¬ ( ∃ x G ∧ F ) {\displaystyle (\exists xG\land \neg F)=\neg \ (\exists xG\land F)} = ( ∃ x ¬ G ∨ ¬ F ) {\displaystyle =(\exists x\neg G\lor \neg F)} Gが偽の場合、これは偽です。この矛盾を避けるため、 Fは ブール型であってはなりません。ブール型 F の場合、ドロップルールの正しい記述は等式ではなく含意を用いています。
x ∉ FV ( E ) ∧ x ∈ FV ( F ) ⟹ ( let x : G in E F → E ( let x : G in F ) ) {\displaystyle x\not \in \operatorname {FV} (E)\land x\in \operatorname {FV} (F)\implies (\operatorname {let} x:G\operatorname {in} E\ F\to E\ (\operatorname {let} x:G\operatorname {in} F))} ブール型に他の型とは異なるルールが適用されるのは奇妙に思えるかもしれません。その理由は、
( ∃ x E ∧ F ) ⟺ let x : E in F {\displaystyle (\exists xE\land F)\iff \operatorname {let} x:E\operatorname {in} F} F がブール値の場合にのみ適用されます 。2つの規則を組み合わせると矛盾が生じ、一方の規則が成立する場合、もう一方の規則は成立しません。
let式の結合 Let式は複数の変数で定義できます。
( ∃ v ⋯ ∃ w ∃ x E ∧ F ) ⟺ let v , … , w , x : E in F {\displaystyle (\exists v\cdots \exists w\exists xE\land F)\iff \operatorname {let} v,\ldots ,w,x:E\operatorname {in} F} すると、
x ∉ F V ( E ) ⟹ ( ∃ v ⋯ ∃ w ∃ x E ∧ F ) ⟺ ( ∃ v ⋯ ∃ w ( E ∧ ∃ x F ) ) {\displaystyle x\not \in FV(E)\implies (\exists v\cdots \exists w\exists xE\land F)\iff (\exists v\cdots \exists w(E\land \exists xF))} それで、
x ∉ F V ( E ) ⟹ ( let v , … , w , x : E ∧ F in L ≡ let v , … , w : E in let x : F in L ) {\displaystyle x\not \in FV(E)\implies (\operatorname {let} v,\ldots ,w,x:E\land F\operatorname {in} L\equiv \operatorname {let} v,\ldots ,w:E\operatorname {in} \operatorname {let} x:F\operatorname {in} L)}
ラムダ計算とlet式に関する法則 イータ 還元は、 ラムダ抽象化を記述するための規則を与えます。この規則は、上で導出された2つの法則と併せて、ラムダ計算とlet式の関係を定義します。
名前 法 イータ還元等価性 f x = y ≡ f = λ x . y {\displaystyle f\ x=y\equiv f=\lambda x.y} Let-lambda同値性 f ∉ F V ( E ) ⟹ ( let f : f = E in L ≡ ( λ f . L ) E ) {\displaystyle f\notin FV(E)\implies (\operatorname {let} f:f=E\operatorname {in} L\equiv (\lambda f.L)\ E)} (ここで は変数名です。) f {\displaystyle f} 組み合わせてみましょう x ∉ F V ( E ) ⟹ ( let v , … , w , x : E ∧ F in L ≡ let v , … , w : E in let x : F in L ) {\displaystyle x\notin FV(E)\implies (\operatorname {let} v,\dots ,w,x:E\land F\operatorname {in} L\equiv \operatorname {let} v,\dots ,w:E\operatorname {in} \operatorname {let} x:F\operatorname {in} L)}
ラムダ計算から定義されたlet定義 数学的定義に伴う潜在的な問題を回避するため、 ダナ・スコットはラムダ計算から let 式を独自に定義しました。これは、トップダウン 型、つまり公理的な数学的定義とは対照的に、 ボトム アップ型、つまり構成的定義であると考えられます。
単純で非再帰的な let 式は、項に適用されるラムダ抽象化の 糖衣構文 として定義されました。その定義では、
( let s x = y in z ) ≡ ( λ x . z ) y {\displaystyle (\operatorname {let} _{s}x=y\operatorname {in} z)\equiv (\lambda x.z)\ y} その後、単純な let式の定義が拡張され、 固定小数点コンビネータ を使用した再帰が可能になりました 。
固定小数点コンビネータ 固定 小数点コンビネータは 次の式で表されます。
λ f . let x = f x in x {\displaystyle \lambda f.\operatorname {let} x=f\ x\operatorname {in} x} この表現はラムダ項に変換できます。ラムダ抽象化では、適用された式内で変数名への参照をサポートしていないため、 x は x のパラメータとして渡す必要があります 。
λ f . let x x = f ( x x ) in x x {\displaystyle \lambda f.\operatorname {let} x\ x=f\ (x\ x)\operatorname {in} x\ x} イータ減少則を用いると、
f x = y ≡ f = λ x . y {\displaystyle f\ x=y\equiv f=\lambda x.y} 与える、
λ f . let x = λ x . f ( x x ) in x x {\displaystyle \lambda f.\operatorname {let} x=\lambda x.f\ (x\ x)\operatorname {in} x\ x} let式は、次のようにラムダ抽象化として表現できる。
n ∉ F V ( E ) → ( let n = E in L ≡ ( λ n . L ) E ) {\displaystyle n\not \in FV(E)\to (\operatorname {let} n=E\operatorname {in} L\equiv (\lambda n.L)\ E)} 与える、
λ f . ( λ x . x x ) ( λ x . f ( x x ) ) {\displaystyle \lambda f.(\lambda x.x\ x)\ (\lambda x.f\ (x\ x))} これはおそらくラムダ計算における不動点コンビネータの最も単純な実装です。しかし、ベータ還元を1つ行うことで、CurryのYコンビネータのより対称的な形が得られます。
λ f . ( λ x . f ( x x ) ) ( λ x . f ( x x ) ) {\displaystyle \lambda f.(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x))}
再帰let式 「let rec」と呼ばれる再帰 let 式は、再帰 let 式の Y コンビネータを使用して定義されます。
( l e t r e c x = y in z ) ≡ ( λ x . z ) ( Y ( λ x . y ) ) {\displaystyle (\operatorname {let\ rec} x=y\operatorname {in} z)\equiv (\lambda x.z)\ (Y\ (\lambda x.y))}
相互再帰let式 このアプローチは、相互再帰をサポートするために一般化されます。相互再帰的なlet式は、式を並べ替えてand条件を削除することで構成できます。これは、複数の関数定義を単一の関数定義に置き換えることで実現され、変数のリストが式のリストと等しくなります。次に、Yコンビネータの一種である Y* 多変数固定小数点コンビネータ [5] を使用して、すべての関数の固定小数点を同時に計算します。その結果、 let 式の相互再帰的な実装が得られます。
複数の値 let式は集合の要素である値を表すために使われる。
let x ∈ X in x {\displaystyle \operatorname {let} x\in X\operatorname {in} x} 関数適用 では 、あるlet式を別のlet式に適用すると、
( let x ∈ X in x ) ( let y ∈ Y in y ) = let x ∈ X ∧ y ∈ Y in x y = let ( x , y ) ∈ X × Y in x y {\displaystyle {\begin{aligned}&(\operatorname {let} x\in X\operatorname {in} x)\ (\operatorname {let} y\in Y\operatorname {in} y)\\&=\operatorname {let} x\in X\land y\in Y\operatorname {in} x\ y\\&=\operatorname {let} (x,y)\in X\times Y\operatorname {in} x\ y\end{aligned}}} ただし、let 式をそれ自身に適用する場合は、異なるルールが適用されます。
( let x ∈ X in x ) ( let x ∈ X in x ) = let x ∈ X in x x {\displaystyle {\begin{aligned}&(\operatorname {let} x\in X\operatorname {in} x)\ (\operatorname {let} x\in X\operatorname {in} x)\\&=\operatorname {let} x\in X\operatorname {in} x\ x\end{aligned}}} 値の組み合わせに関する単純なルールは見当たりません。必要なのは、値が値の集合のメンバーである変数を表す一般的な表現形式です。表現は、変数と集合に基づいて記述する必要があります。
この形式に関数を適用すると、同じ形式の別の式が生成されます。このように、複数の値を持つ関数の式は、1つの値を持つかのように扱うことができます。
形式が値の集合のみを表すだけでは不十分です。それぞれの値には、式がいつその値を取るかを決定する条件が必要です。結果として得られる構成は、条件と値のペアの集合であり、「値集合」と呼ばれます。 代数的値集合の狭まりを 参照してください。
ラムダ計算とlet式間の変換規則 lambda式 と let式間の変換を記述する メタ関数 を示します 。メタ関数とは、プログラムをパラメータとして受け取る関数です。プログラムはメタプログラムのデータです。プログラムとメタプログラムは異なるメタレベルにあります。
プログラムとメタプログラムを区別するために、以下の規則が使用されます。
角括弧 [] は、メタプログラム内の関数の適用を表すために使用されます。 メタプログラム内の変数には大文字が使用されます。プログラム内の変数は小文字で表されます。 ≡ {\displaystyle \equiv } メタプログラム内のequalsに使用されます。 簡潔にするために、最初のルールが適用されます。また、これらのルールでは、ラムダ式が前処理され、各ラムダ抽象化に一意の名前が付けられていることを前提としています。
置換演算子も使用されます。式は、 L 内の Gをすべて S に 置き換え、その結果を返すことを意味します。使用される定義は、 ラムダ計算の ページに記載されている定義を拡張して、式の置換もカバーするようにしています 。式のマッチングでは、式のアルファ同値性(変数名の変更)を比較する必要があります。 L [ G := S ] {\displaystyle L[G:=S]}
ラムダ式からlet式への変換 次の規則は、構造を変更せずに ラムダ式から let式に変換する方法について説明しています。
d e - l a m b d a [ V ] ≡ V {\displaystyle \operatorname {de-lambda} [V]\equiv V} d e - l a m b d a [ M N ] ≡ d e - l a m b d a [ M ] d e - l a m b d a [ N ] {\displaystyle \operatorname {de-lambda} [M\ N]\equiv \operatorname {de-lambda} [M]\ \operatorname {de-lambda} [N]} d e - l a m b d a [ F = λ P . E ] ≡ d e - l a m b d a [ F P = E ] {\displaystyle \operatorname {de-lambda} [F=\lambda P.E]\equiv \operatorname {de-lambda} [F\ P=E]} d e - l a m b d a [ E = F ] ≡ d e - l a m b d a [ E ] = d e - l a m b d a [ F ] {\displaystyle \operatorname {de-lambda} [E=F]\equiv \operatorname {de-lambda} [E]=\operatorname {de-lambda} [F]} d e - l a m b d a [ ( λ F . E ) L ] ≡ l e t - c o m b i n e [ let F : d e - l a m b d a [ F = L ] in E ] {\displaystyle \operatorname {de-lambda} [(\lambda F.E)L]\equiv \operatorname {let-combine} [\operatorname {let} F:\operatorname {de-lambda} [F=L]\operatorname {in} E]} V ∉ FV [ λ F . E ] → d e - l a m b d a [ λ F . E ] ≡ l e t - c o m b i n e [ let V : d e - l a m b d a [ V F = E ] in V ] {\displaystyle V\not \in \operatorname {FV} [\lambda F.E]\to \operatorname {de-lambda} [\lambda F.E]\equiv \operatorname {let-combine} [\operatorname {let} V:\operatorname {de-lambda} [V\ F=E]\operatorname {in} V]} V ≠ W → l e t - c o m b i n e [ let V : E in let W : F in G ] ≡ let V , W : E ∧ F in G {\displaystyle V\neq W\to \operatorname {let-combine} [\operatorname {let} V:E\operatorname {in} \operatorname {let} W:F\operatorname {in} G]\equiv \operatorname {let} V,W:E\land F\operatorname {in} G} l e t - c o m b i n e [ let V : E in F ] ≡ let V : E in F {\displaystyle \operatorname {let-combine} [\operatorname {let} V:E\operatorname {in} F]\equiv \operatorname {let} V:E\operatorname {in} F} ルール 6 は、関数の名前として一意の変数 V を作成します。
例 例えば、 Yコンビネータ 、
λ f . ( λ x . f ( x x ) ) ( λ x . f ( x x ) ) {\displaystyle \lambda f.(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x))} に変換されます。
let p : p f = let x : x q = f ( q q ) in f ( x x ) in p {\displaystyle \operatorname {let} p:p\ f=\operatorname {let} x:x\ q=f\ (q\ q)\operatorname {in} f\ (x\ x)\operatorname {in} p} ルール ラムダ式 6 d e - l a m b d a [ λ f . ( λ x . f ( x x ) ) ( λ x . f ( x x ) ) ] {\displaystyle \operatorname {de-lambda} [\lambda f.(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x))]} V ∉ FV [ λ F . E ] → d e - l a m b d a [ λ F . E ] {\displaystyle V\not \in \operatorname {FV} [\lambda F.E]\to \operatorname {de-lambda} [\lambda F.E]} V = p , F = f , E = ( λ x . f ( x x ) ) ( λ x . f ( x x ) ) {\displaystyle V=p,F=f,E=(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x))} l e t - c o m b i n e [ let V : d e - l a m b d a [ V F = E ] in V ] {\displaystyle \operatorname {let-combine} [\operatorname {let} V:\operatorname {de-lambda} [V\ F=E]\operatorname {in} V]}
4 l e t - c o m b i n e [ let p : d e - l a m b d a [ p f = ( λ x . f ( x x ) ) ( λ x . f ( x x ) ) ] in p ] {\displaystyle \operatorname {let-combine} [\operatorname {let} p:\operatorname {de-lambda} [p\ f=(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x))]\operatorname {in} p]} d e - l a m b d a [ p f = ( λ x . f ( x x ) ) ( λ x . f ( x x ) ) ] {\displaystyle \operatorname {de-lambda} [p\ f=(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x))]} d e - l a m b d a [ E = F ] {\displaystyle \operatorname {de-lambda} [E=F]} E = p f , F = ( λ x . f ( x x ) ) ( λ x . f ( x x ) ) {\displaystyle E=p\ f,F=(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x))} d e - l a m b d a [ E ] = d e - l a m b d a [ F ] {\displaystyle \operatorname {de-lambda} [E]=\operatorname {de-lambda} [F]} d e - l a m b d a [ p f ] = d e - l a m b d a [ ( λ x . f ( x x ) ) ( λ x . f ( x x ) ) ] {\displaystyle \operatorname {de-lambda} [p\ f]=\operatorname {de-lambda} [(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x))]} l e t - c o m b i n e [ let p : d e - l a m b d a [ p f ] = d e - l a m b d a [ ( λ x . f ( x x ) ) ( λ x . f ( x x ) ) ] in p ] {\displaystyle \operatorname {let-combine} [\operatorname {let} p:\operatorname {de-lambda} [p\ f]=\operatorname {de-lambda} [(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x))]\operatorname {in} p]}
5 l e t - c o m b i n e [ let p : d e - l a m b d a [ p f ] = d e - l a m b d a [ ( λ x . f ( x x ) ) ( λ x . f ( x x ) ) ] in p ] {\displaystyle \operatorname {let-combine} [\operatorname {let} p:\operatorname {de-lambda} [p\ f]=\operatorname {de-lambda} [(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x))]\operatorname {in} p]} d e - l a m b d a [ ( λ x . f ( x x ) ) ( λ x . f ( x x ) ) ] {\displaystyle \operatorname {de-lambda} [(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x))]} d e - l a m b d a [ ( λ F . E ) L ] {\displaystyle \operatorname {de-lambda} [(\lambda F.E)L]} F = x , E = f ( x x ) , L = ( λ x . f ( x x ) ) {\displaystyle F=x,E=f\ (x\ x),L=(\lambda x.f\ (x\ x))} l e t - c o m b i n e [ let F : d e - l a m b d a [ F = L ] in E ] {\displaystyle \operatorname {let-combine} [\operatorname {let} F:\operatorname {de-lambda} [F=L]\operatorname {in} E]} l e t - c o m b i n e [ let x : d e - l a m b d a [ x = λ x . f ( x x ) ] in f ( x x ) ] {\displaystyle \operatorname {let-combine} [\operatorname {let} x:\operatorname {de-lambda} [x=\lambda x.f\ (x\ x)]\operatorname {in} f\ (x\ x)]}
3 l e t - c o m b i n e [ let p : d e - l a m b d a [ p f ] = l e t - c o m b i n e [ let x : d e - l a m b d a [ x = λ x . f ( x x ) ] in f ( x x ) ] in p ] {\displaystyle \operatorname {let-combine} [\operatorname {let} p:\operatorname {de-lambda} [p\ f]=\operatorname {let-combine} [\operatorname {let} x:\operatorname {de-lambda} [x=\lambda x.f\ (x\ x)]\operatorname {in} f\ (x\ x)]\operatorname {in} p]} d e - l a m b d a [ x = λ x . f ( x x ) ] {\displaystyle \operatorname {de-lambda} [x=\lambda x.f\ (x\ x)]} d e - l a m b d a [ F = λ P . E ] {\displaystyle \operatorname {de-lambda} [F=\lambda P.E]} F = x , P = x , E = f ( x x ) {\displaystyle F=x,P=x,E=f\ (x\ x)} d e - l a m b d a [ F P = E ] {\displaystyle \operatorname {de-lambda} [F\ P=E]} d e - l a m b d a [ x x = f ( x x ) ] {\displaystyle \operatorname {de-lambda} [x\ x=f\ (x\ x)]}
8 l e t - c o m b i n e [ let p : d e - l a m b d a [ p f ] = l e t - c o m b i n e [ let x : d e - l a m b d a [ x x = f ( x x ) ] in f ( x x ) ] in p ] {\displaystyle \operatorname {let-combine} [\operatorname {let} p:\operatorname {de-lambda} [p\ f]=\operatorname {let-combine} [\operatorname {let} x:\operatorname {de-lambda} [x\ x=f\ (x\ x)]\operatorname {in} f\ (x\ x)]\operatorname {in} p]} l e t - c o m b i n e [ let x : d e - l a m b d a [ x x = f ( x x ) ] in f ( x x ) ] {\displaystyle \operatorname {let-combine} [\operatorname {let} x:\operatorname {de-lambda} [x\ x=f\ (x\ x)]\operatorname {in} f\ (x\ x)]} l e t - c o m b i n e [ Y ] {\displaystyle \operatorname {let-combine} [Y]} Y = let x : d e - l a m b d a [ x x = f ( x x ) ] in f ( x x ) {\displaystyle Y=\operatorname {let} x:\operatorname {de-lambda} [x\ x=f\ (x\ x)]\operatorname {in} f\ (x\ x)} Y {\displaystyle Y} let x : d e - l a m b d a [ x x = f ( x x ) ] in f ( x x ) {\displaystyle \operatorname {let} x:\operatorname {de-lambda} [x\ x=f\ (x\ x)]\operatorname {in} f\ (x\ x)}
8 l e t - c o m b i n e [ let p : d e - l a m b d a [ p f ] = let x : d e - l a m b d a [ x x = f ( x x ) ] in f ( x x ) in p ] {\displaystyle \operatorname {let-combine} [\operatorname {let} p:\operatorname {de-lambda} [p\ f]=\operatorname {let} x:\operatorname {de-lambda} [x\ x=f\ (x\ x)]\operatorname {in} f\ (x\ x)\operatorname {in} p]} l e t - c o m b i n e [ Y ] {\displaystyle \operatorname {let-combine} [Y]} Y = let p : d e - l a m b d a [ p f = let x : d e - l a m b d a [ x x = f ( x x ) ] in f ( x x ) ] in p {\displaystyle Y=\operatorname {let} p:\operatorname {de-lambda} [p\ f=\operatorname {let} x:\operatorname {de-lambda} [x\ x=f\ (x\ x)]\operatorname {in} f\ (x\ x)]\operatorname {in} p} Y {\displaystyle Y} let p : p f = let x : d e - l a m b d a [ x x = f ( x x ) ] in f ( x x ) in p {\displaystyle \operatorname {let} p:p\ f=\operatorname {let} x:\operatorname {de-lambda} [x\ x=f\ (x\ x)]\operatorname {in} f\ (x\ x)\operatorname {in} p}
4 let p : d e - l a m b d a [ p f ] = let x : d e - l a m b d a [ x x = f ( x x ) ] in f ( x x ) in p {\displaystyle \operatorname {let} p:\operatorname {de-lambda} [p\ f]=\operatorname {let} x:\operatorname {de-lambda} [x\ x=f\ (x\ x)]\operatorname {in} f\ (x\ x)\operatorname {in} p} d e - l a m b d a [ x x = f ( x x ) ] {\displaystyle \operatorname {de-lambda} [x\ x=f\ (x\ x)]} d e - l a m b d a [ E = F ] {\displaystyle \operatorname {de-lambda} [E=F]} E = x x , F = f ( x x ) {\displaystyle E=x\ x,F=f\ (x\ x)} d e - l a m b d a [ E ] = d e - l a m b d a [ F ] {\displaystyle \operatorname {de-lambda} [E]=\operatorname {de-lambda} [F]} d e - l a m b d a [ x x ] = d e - l a m b d a [ f ( x x ) ] {\displaystyle \operatorname {de-lambda} [x\ x]=\operatorname {de-lambda} [f\ (x\ x)]}
2 let p : d e - l a m b d a [ p f ] = let x : d e - l a m b d a [ x x ] = d e - l a m b d a [ f ( x x ) ] in f ( x x ) in p {\displaystyle \operatorname {let} p:\operatorname {de-lambda} [p\ f]=\operatorname {let} x:\operatorname {de-lambda} [x\ x]=\operatorname {de-lambda} [f\ (x\ x)]\operatorname {in} f\ (x\ x)\operatorname {in} p} d e - l a m b d a [ x x ] , d e - l a m b d a [ f ( x x ) ] {\displaystyle \operatorname {de-lambda} [x\ x],\operatorname {de-lambda} [f\ (x\ x)]} d e - l a m b d a [ p f ] , d e - l a m b d a [ M 1 N 1 ] , d e - l a m b d a [ M 2 N 2 ] , {\displaystyle \operatorname {de-lambda} [p\ f],\operatorname {de-lambda} [M_{1}\ N_{1}],\operatorname {de-lambda} [M_{2}\ N_{2}],} M 1 = p , N 1 = f , M 2 = x , N 2 = x , M 3 = f , N 3 = x x {\displaystyle M_{1}=p,N_{1}=f,M_{2}=x,N_{2}=x,M_{3}=f,N_{3}=x\ x} d e - l a m b d a [ M 1 ] d e - l a m b d a [ N 1 ] , d e - l a m b d a [ M 2 ] d e - l a m b d a [ N 2 ] , d e - l a m b d a [ M 3 ] d e - l a m b d a [ N 3 ] {\displaystyle \operatorname {de-lambda} [M_{1}]\ \operatorname {de-lambda} [N_{1}],\operatorname {de-lambda} [M_{2}]\ \operatorname {de-lambda} [N_{2}],\operatorname {de-lambda} [M_{3}]\ \operatorname {de-lambda} [N_{3}]} d e - l a m b d a [ p ] d e - l a m b d a [ f ] , d e - l a m b d a [ x ] d e - l a m b d a [ x ] , d e - l a m b d a [ f ] d e - l a m b d a [ x ] d e - l a m b d a [ x ] {\displaystyle \operatorname {de-lambda} [p]\ \operatorname {de-lambda} [f],\operatorname {de-lambda} [x]\ \operatorname {de-lambda} [x],\operatorname {de-lambda} [f]\ \operatorname {de-lambda} [x]\ \operatorname {de-lambda} [x]}
1 let p : d e - l a m b d a [ p ] d e - l a m b d a [ f ] = let x : d e - l a m b d a [ x ] d e - l a m b d a [ x ] = d e - l a m b d a [ f ] ( d e - l a m b d a [ x ] d e - l a m b d a [ x ] ) in f ( x x ) ] in p {\displaystyle \operatorname {let} p:\operatorname {de-lambda} [p]\ \operatorname {de-lambda} [f]=\operatorname {let} x:\operatorname {de-lambda} [x]\ \operatorname {de-lambda} [x]=\operatorname {de-lambda} [f]\ (\operatorname {de-lambda} [x]\ \operatorname {de-lambda} [x])\operatorname {in} f\ (x\ x)]\operatorname {in} p} d e - l a m b d a [ V ] {\displaystyle \operatorname {de-lambda} [V]} V {\displaystyle V}
let p : p f = let x : x x = f ( x x ) in f ( x x ) ] in p {\displaystyle \operatorname {let} p:p\ f=\operatorname {let} x:x\ x=f\ (x\ x)\operatorname {in} f\ (x\ x)]\operatorname {in} p}
let式からlambda式への変換 これらの規則は、上記の変換を逆にします。let 式を lambda 式に変換しますが 、 構造は変更しません。ただし、すべての let 式がこれらの規則を用いて変換できるわけではありません。これらの規則は、式が de-lambda によって生成されたかのように既に配置されていることを前提としています。
g e t - l a m b d a [ F , G V = E ] = g e t - l a m b d a [ F , G = λ V . E ] {\displaystyle \operatorname {get-lambda} [F,G\ V=E]=\operatorname {get-lambda} [F,G=\lambda V.E]} g e t - l a m b d a [ F , F = E ] = d e - l e t [ E ] {\displaystyle \operatorname {get-lambda} [F,F=E]=\operatorname {de-let} [E]} d e - l e t [ λ V . E ] ≡ λ V . d e - l e t [ E ] {\displaystyle \operatorname {de-let} [\lambda V.E]\equiv \lambda V.\operatorname {de-let} [E]} d e - l e t [ M N ] ≡ d e - l e t [ M ] d e - l e t [ N ] {\displaystyle \operatorname {de-let} [M\ N]\equiv \operatorname {de-let} [M]\ \operatorname {de-let} [N]} d e - l e t [ V ] ≡ V {\displaystyle \operatorname {de-let} [V]\equiv V} V ∉ F V [ g e t - l a m b d a [ V , E ] ] → d e - l e t [ let V : E in V ] ≡ g e t - l a m b d a [ V , E ] {\displaystyle V\not \in FV[\operatorname {get-lambda} [V,E]]\to \operatorname {de-let} [\operatorname {let} V:E\ \operatorname {in} V]\equiv \operatorname {get-lambda} [V,E]} V ∉ F V [ g e t - l a m b d a [ V , E ] ] → d e - l e t [ let V : E in L ] ≡ ( λ V . d e - l e t [ L ] ) g e t - l a m b d a [ V , E ] {\displaystyle V\not \in FV[\operatorname {get-lambda} [V,E]]\to \operatorname {de-let} [\operatorname {let} V:E\ \operatorname {in} L]\equiv (\lambda V.\operatorname {de-let} [L])\ \operatorname {get-lambda} [V,E]} W ∉ FV [ g e t - l a m b d a [ V , E ] ] → d e - l e t [ let V , W : E ∧ F in G ] ≡ d e - l e t [ let V : E in let W : F in G ] {\displaystyle W\not \in \operatorname {FV} [\operatorname {get-lambda} [V,E]]\to \operatorname {de-let} [\operatorname {let} V,W:E\land F\ \operatorname {in} G]\equiv \operatorname {de-let} [\operatorname {let} V:E\ \operatorname {in} \operatorname {let} W:F\ \operatorname {in} G]} V ∈ FV [ g e t - l a m b d a [ V , E ] ] → d e - l e t [ let V : E in L ] ≡ d e - l e t [ let V : V V = g e t - l a m b d a [ V , E ] [ V := V V ] in L [ V := V V ] ] {\displaystyle V\in \operatorname {FV} [\operatorname {get-lambda} [V,E]]\to \operatorname {de-let} [\operatorname {let} V:E\ \operatorname {in} L]\equiv \operatorname {de-let} [\operatorname {let} V:V\ V=\operatorname {get-lambda} [V,E][V:=V\ V]\ \operatorname {in} L[V:=V\ V]]} W ∈ FV [ g e t - l a m b d a [ V , E ] ] → d e - l e t [ let V , W : E ∧ F in L ] ≡ d e - l e t [ let V : V W = g e t - l a m b d a [ V , E ] [ V := V W ] in let W : F [ V := V W ] in L [ V := V W ] ] {\displaystyle W\in \operatorname {FV} [\operatorname {get-lambda} [V,E]]\to \operatorname {de-let} [\operatorname {let} V,W:E\land F\ \operatorname {in} L]\equiv \operatorname {de-let} [\operatorname {let} V:V\ W=\operatorname {get-lambda} [V,E][V:=V\ W]\ \operatorname {in} \operatorname {let} W:F[V:=V\ W]\ \operatorname {in} L[V:=V\ W]]} ラムダ計算には、再帰的に使用される自由変数を持つlet 式と全く同じ構造を持つものはありません 。この場合、パラメータを追加する必要があります。規則8と10はこれらのパラメータを追加します。
ルール8と10は、 let 式内の相互再帰方程式が2つであれば十分です 。しかし、相互再帰方程式が3つ以上ある場合は機能しません。一般的なケースではループ処理が1段階追加されるため、メタ関数の実装が少し難しくなります。以下のルールは、一般的なケースを実装する際にルール8と10を置き換えます。ルール8と10は、より単純なケースを先に検討できるように残されています。
lambda-form - 式を、それぞれが 変数 = 式 という形式の式の連結に変換します 。 l a m b d a - f o r m [ G V = E ] = l a m b d a - f o r m [ G = λ V . E ] {\displaystyle \operatorname {lambda-form} [G\ V=E]=\operatorname {lambda-form} [G=\lambda V.E]} l a m b d a - f o r m [ E ∧ F ] = l a m b d a - f o r m [ E ] ∧ l a m b d a - f o r m [ F ] {\displaystyle \operatorname {lambda-form} [E\land F]=\operatorname {lambda-form} [E]\land \operatorname {lambda-form} [F]} l a m b d a - f o r m [ V = E ] = V = E {\displaystyle \operatorname {lambda-form} [V=E]=V=E} ......ここで、 V は変数です。 lift-vars -式には 自由変数として Xがあるため、パラメーターとして X を必要とする変数のセットを取得します。 X ∈ FV [ E ] → l i f t - v a r s [ X , V = E ] = { V } {\displaystyle X\in \operatorname {FV} [E]\to \operatorname {lift-vars} [X,V=E]=\{V\}} X ∉ FV [ E ] → l i f t - v a r s [ X , V = E ] = { } {\displaystyle X\not \in \operatorname {FV} [E]\to \operatorname {lift-vars} [X,V=E]=\{\}} l i f t - v a r s [ X , E ∧ F ] = l i f t - v a r s [ X , E ] ∪ l i f t - v a r s [ X . F ] {\displaystyle \operatorname {lift-vars} [X,E\land F]=\operatorname {lift-vars} [X,E]\cup \operatorname {lift-vars} [X.F]} サブ変数 - セット内の各変数を、式内のXに適用されている変数に置き換えます。これにより、 Xは 式の右辺の自由変数ではなく、パラメータとして渡される変数になります。 s u b - v a r s [ E , { V } ∪ S , X ] = s u b - v a r s [ E [ V := V X ] , S , X ] {\displaystyle \operatorname {sub-vars} [E,\{V\}\cup S,X]=\operatorname {sub-vars} [E[V:=V\ X],S,X]} s u b - v a r s [ E , { } , X ] = E {\displaystyle \operatorname {sub-vars} [E,\{\},X]=E} de-let - E の各条件 を解除して、 X が 方程式の右側の自由変数にならない ようにします。 L = l a m b d a - f o r m [ E ] ∧ S = l i f t - v a r s [ X , L ] → d e - l e t [ let V … W , X : E ∧ F in G ] ≡ d e - l e t [ let V … W : s u b - v a r s [ L , S , X ] in let s u b - v a r s [ l a m b d a - f o r m [ F ] , S , X ] in s u b - v a r s [ G , S , X ] ] {\displaystyle {\begin{aligned}L&=\operatorname {lambda-form} [E]\land S=\operatorname {lift-vars} [X,L]\to \operatorname {de-let} [\operatorname {let} V\ldots W,X:E\land F\ \operatorname {in} G]\\&\equiv \operatorname {de-let} [\operatorname {let} V\ldots W:\operatorname {sub-vars} [L,S,X]\ \operatorname {in} \operatorname {let} \operatorname {sub-vars} [\operatorname {lambda-form} [F],S,X]\ \operatorname {in} \operatorname {sub-vars} [G,S,X]]\end{aligned}}}
例 例えば、 Yコンビネータ から得られる let 式は、
let p : p f = let x : x q = f ( q q ) in f ( x x ) in p {\displaystyle \operatorname {let} p:p\ f=\operatorname {let} x:x\ q=f\ (q\ q)\ \operatorname {in} f\ (x\ x)\ \operatorname {in} p} に変換されます。
λ f . ( λ x . f ( x x ) ) ( λ q . f ( q q ) ) {\displaystyle \lambda f.(\lambda x.f\ (x\ x))\ (\lambda q.f\ (q\ q))} ルール ラムダ式 6 d e - l e t [ let p : p f = let x : x q = f ( q q ) in f ( x x ) in p ] {\displaystyle \operatorname {de-let} [\operatorname {let} p:p\ f=\operatorname {let} x:x\ q=f\ (q\ q)\ \operatorname {in} f\ (x\ x)\ \operatorname {in} p]} d e - l e t [ let V : E in V ] {\displaystyle \operatorname {de-let} [\operatorname {let} V:E\ \operatorname {in} V]} V = p , E = p f = let x : x q = f ( q q ) in f ( x x ) {\displaystyle V=p,E=p\ f=\operatorname {let} x:x\ q=f\ (q\ q)\ \operatorname {in} f\ (x\ x)} g e t - l a m b d a [ V , E ] {\displaystyle \operatorname {get-lambda} [V,E]}
1 g e t - l a m b d a [ p , p f = let x : x q = f ( q q ) in f ( x x ) ] {\displaystyle \operatorname {get-lambda} [p,p\ f=\operatorname {let} x:x\ q=f\ (q\ q)\ \operatorname {in} f\ (x\ x)]} g e t - l a m b d a [ F , G V = E ] {\displaystyle \operatorname {get-lambda} [F,G\ V=E]} F = p , G = p , V = f , E = let x : x q = f ( q q ) in f ( x x ) {\displaystyle F=p,G=p,V=f,E=\operatorname {let} x:x\ q=f\ (q\ q)\ \operatorname {in} f\ (x\ x)} g e t - l a m b d a [ F , G = λ V . E ] {\displaystyle \operatorname {get-lambda} [F,G=\lambda V.E]}
2 g e t - l a m b d a [ p , p = λ f . let x : x q = f ( q q ) in f ( x x ) ] {\displaystyle \operatorname {get-lambda} [p,p=\lambda f.\operatorname {let} x:x\ q=f\ (q\ q)\ \operatorname {in} f\ (x\ x)]} g e t - l a m b d a [ F , F = E ] {\displaystyle \operatorname {get-lambda} [F,F=E]} F = p , E = λ f . let x : x q = f ( q q ) in f ( x x ) {\displaystyle F=p,E=\lambda f.\operatorname {let} x:x\ q=f\ (q\ q)\ \operatorname {in} f\ (x\ x)} d e - l e t [ E ] {\displaystyle \operatorname {de-let} [E]}
3 d e - l e t [ λ f . let x : x q = f ( q q ) in f ( x x ) ] {\displaystyle \operatorname {de-let} [\lambda f.\operatorname {let} x:x\ q=f\ (q\ q)\ \operatorname {in} f\ (x\ x)]} d e - l e t [ λ V . E ] {\displaystyle \operatorname {de-let} [\lambda V.E]} V = f , E = let x : x q = f ( q q ) in f ( x x ) {\displaystyle V=f,E=\operatorname {let} x:x\ q=f\ (q\ q)\ \operatorname {in} f\ (x\ x)} λ V . d e - l e t [ E ] {\displaystyle \lambda V.\operatorname {de-let} [E]}
7 λ f . d e - l e t [ let x : x q = f ( q q ) in f ( x x ) ] {\displaystyle \lambda f.\operatorname {de-let} [\operatorname {let} x:x\ q=f\ (q\ q)\ \operatorname {in} f\ (x\ x)]} d e - l e t [ let x : x q = f ( q q ) in f ( x x ) ] {\displaystyle \operatorname {de-let} [\operatorname {let} x:x\ q=f\ (q\ q)\ \operatorname {in} f\ (x\ x)]} V ∉ F V [ g e t - l a m b d a [ V , E ] ] → d e - l e t [ let V : E in L ] {\displaystyle V\not \in FV[\operatorname {get-lambda} [V,E]]\to \operatorname {de-let} [\operatorname {let} V:E\ \operatorname {in} L]} V = x , E = x q = f ( q q ) , L = f ( x x ) {\displaystyle V=x,E=x\ q=f\ (q\ q),L=f\ (x\ x)} ( λ V . d e - l e t [ L ] ) g e t - l a m b d a [ V , E ] {\displaystyle (\lambda V.\operatorname {de-let} [L])\ \operatorname {get-lambda} [V,E]}
4 ( λ x . d e - l e t [ f ( x x ) ] ) g e t - l a m b d a [ x , x q = f ( q q ) ] {\displaystyle (\lambda x.\operatorname {de-let} [f\ (x\ x)])\ \operatorname {get-lambda} [x,x\ q=f\ (q\ q)]} d e - l e t [ f ( x x ) ] {\displaystyle \operatorname {de-let} [f\ (x\ x)]} d e - l e t [ M N ] {\displaystyle \operatorname {de-let} [M\ N]} M = f , N = ( x x ) {\displaystyle M=f,N=(x\ x)} d e - l e t [ M ] d e - l e t [ N ] {\displaystyle \operatorname {de-let} [M]\ \operatorname {de-let} [N]} d e - l e t [ f ] d e - l e t [ x x ] {\displaystyle \operatorname {de-let} [f]\ \operatorname {de-let} [x\ x]}
4 ( λ x . d e - l e t [ f ] d e - l e t [ x x ] ) g e t - l a m b d a [ x , x q = f ( q q ) ] {\displaystyle (\lambda x.\operatorname {de-let} [f]\ \operatorname {de-let} [x\ x])\ \operatorname {get-lambda} [x,x\ q=f\ (q\ q)]} d e - l e t [ x x ] {\displaystyle \operatorname {de-let} [x\ x]} d e - l e t [ M N ] {\displaystyle \operatorname {de-let} [M\ N]} M = x , N = x {\displaystyle M=x,N=x} d e - l e t [ M ] d e - l e t [ N ] {\displaystyle \operatorname {de-let} [M]\ \operatorname {de-let} [N]} d e - l e t [ x ] d e - l e t [ x ] {\displaystyle \operatorname {de-let} [x]\ \operatorname {de-let} [x]}
5 ( λ x . d e - l e t [ f ] ( d e - l e t [ x ] d e - l e t [ x ] ) ) g e t - l a m b d a [ x , x q = f ( q q ) ] {\displaystyle (\lambda x.\operatorname {de-let} [f]\ (\operatorname {de-let} [x]\ \operatorname {de-let} [x]))\ \operatorname {get-lambda} [x,x\ q=f\ (q\ q)]} d e - l e t [ V ] {\displaystyle \operatorname {de-let} [V]} V {\displaystyle V}
1 ( λ x . f ( x x ) ) g e t - l a m b d a [ x , x q = f ( q q ) ] {\displaystyle (\lambda x.f\ (x\ x))\ \operatorname {get-lambda} [x,x\ q=f\ (q\ q)]} g e t - l a m b d a [ x , x q = f ( q q ) ] {\displaystyle \operatorname {get-lambda} [x,x\ q=f\ (q\ q)]} g e t - l a m b d a [ F , G V = E ] {\displaystyle \operatorname {get-lambda} [F,G\ V=E]} F = x , G = x , V = q , E = f ( q q ) {\displaystyle F=x,G=x,V=q,E=f\ (q\ q)} g e t - l a m b d a [ F , G = λ V . E ] {\displaystyle \operatorname {get-lambda} [F,G=\lambda V.E]} g e t - l a m b d a [ x , x = λ q . f ( q q ) ] {\displaystyle \operatorname {get-lambda} [x,x=\lambda q.f\ (q\ q)]}
2 ( λ x . f ( x x ) ) g e t - l a m b d a [ x , x = λ q . f ( q q ) ] {\displaystyle (\lambda x.f\ (x\ x))\ \operatorname {get-lambda} [x,x=\lambda q.f\ (q\ q)]} g e t - l a m b d a [ x , x = λ q . f ( q q ) ] {\displaystyle \operatorname {get-lambda} [x,x=\lambda q.f\ (q\ q)]} g e t - l a m b d a [ F , F = E ] {\displaystyle \operatorname {get-lambda} [F,F=E]} F = x , E = λ q . f ( q q ) {\displaystyle F=x,E=\lambda q.f\ (q\ q)} d e - l e t [ E ] {\displaystyle \operatorname {de-let} [E]} d e - l e t [ λ q . f ( q q ) ] {\displaystyle \operatorname {de-let} [\lambda q.f\ (q\ q)]}
3 ( λ x . f ( x x ) ) d e - l e t [ λ q . f ( q q ) ] {\displaystyle (\lambda x.f\ (x\ x))\ \operatorname {de-let} [\lambda q.f\ (q\ q)]} d e - l e t [ λ q . f ( q q ) ] {\displaystyle \operatorname {de-let} [\lambda q.f\ (q\ q)]} d e - l e t [ λ V . E ] {\displaystyle \operatorname {de-let} [\lambda V.E]} V = q , E = f ( q q ) {\displaystyle V=q,E=f\ (q\ q)} λ V . d e - l e t [ E ] {\displaystyle \lambda V.\operatorname {de-let} [E]} λ q . d e - l e t [ f ( q q ) ] {\displaystyle \lambda q.\operatorname {de-let} [f\ (q\ q)]}
4 ( λ x . f ( x x ) ) ( λ q . d e - l e t [ f ( q q ) ] ) {\displaystyle (\lambda x.f\ (x\ x))\ (\lambda q.\operatorname {de-let} [f\ (q\ q)])} d e - l e t [ f ( q q ) ] {\displaystyle \operatorname {de-let} [f\ (q\ q)]} d e - l e t [ M 1 N 1 ] {\displaystyle \operatorname {de-let} [M_{1}\ N_{1}]} M 1 = f , N 1 = q q {\displaystyle M_{1}=f,N_{1}=q\ q} d e - l e t [ M 1 ] d e - l e t [ N 1 ] {\displaystyle \operatorname {de-let} [M_{1}]\ \operatorname {de-let} [N_{1}]} d e - l e t [ f ] d e - l e t [ q q ] {\displaystyle \operatorname {de-let} [f]\ \operatorname {de-let} [q\ q]} d e - l e t [ M 2 N 2 ] {\displaystyle \operatorname {de-let} [M_{2}\ N_{2}]} M 2 = q , N 2 = q {\displaystyle M_{2}=q,N_{2}=q} d e - l e t [ q ] d e - l e t [ q ] {\displaystyle \operatorname {de-let} [q]\ \operatorname {de-let} [q]}
5 ( λ x . f ( x x ) ) ( λ q . d e - l e t [ f ] ( d e - l e t [ q ] d e - l e t [ q ] ) ) {\displaystyle (\lambda x.f\ (x\ x))\ (\lambda q.\operatorname {de-let} [f]\ (\operatorname {de-let} [q]\ \operatorname {de-let} [q]))} d e - l e t [ V ] {\displaystyle \operatorname {de-let} [V]} {\displaystyle } V {\displaystyle V}
( λ x . f ( x x ) ) ( λ q . f ( q q ) ) {\displaystyle (\lambda x.f\ (x\ x))\ (\lambda q.f\ (q\ q))}
2つ目の例として、 Yコンビネータ のリフトバージョンを取り上げます 。
let p , q : p f x = f ( x x ) ∧ q p f = ( p f ) ( p f ) in q p {\displaystyle \operatorname {let} p,q:p\ f\ x=f\ (x\ x)\land q\ p\ f=(p\ f)\ (p\ f)\ \operatorname {in} q\ p} に変換されます。
( λ p . ( λ q . q p ) λ p . λ f . ( p f ) ( p f ) ) λ f . λ x . f ( x x ) {\displaystyle (\lambda p.(\lambda q.q\ p)\ \lambda p.\lambda f.(p\ f)\ (p\ f))\ \lambda f.\lambda x.f\ (x\ x)} ルール ラムダ式 8 d e - l e t [ let p , q : p f x = f ( x x ) ∧ q p f = ( p f ) ( p f ) in q p ] {\displaystyle \operatorname {de-let} [\operatorname {let} p,q:p\ f\ x=f\ (x\ x)\land q\ p\ f=(p\ f)\ (p\ f)\ \operatorname {in} q\ p]} 7 d e - l e t [ let p : p f x = f ( x x ) in let q : q p f = ( p f ) ( p f ) in q p ] {\displaystyle \operatorname {de-let} [\operatorname {let} p:p\ f\ x=f\ (x\ x)\ \operatorname {in} \operatorname {let} q:q\ p\ f=(p\ f)\ (p\ f)\ \operatorname {in} q\ p]} 1、2 ( λ p . d e - l e t [ let q : q p f = ( p f ) ( p f ) in q p ] ) g e t - l a m b d a [ p , p f x = f ( x x ) ] {\displaystyle (\lambda p.\operatorname {de-let} [\operatorname {let} q:q\ p\ f=(p\ f)\ (p\ f)\ \operatorname {in} q\ p])\ \operatorname {get-lambda} [p,p\ f\ x=f\ (x\ x)]} 7、4、5 ( λ p . d e - l e t [ let q : q p f = ( p f ) ( p f ) in q p ] ) λ f . λ x . f ( x x ) {\displaystyle (\lambda p.\operatorname {de-let} [\operatorname {let} q:q\ p\ f=(p\ f)\ (p\ f)\ \operatorname {in} q\ p])\ \lambda f.\lambda x.f\ (x\ x)} 1、2 ( λ p . ( λ q . q p ) g e t - l a m b d a [ q , q p f = ( p f ) ( p f ) ] ) λ f . λ x . f ( x x ) {\displaystyle (\lambda p.(\lambda q.q\ p)\ \operatorname {get-lambda} [q,q\ p\ f=(p\ f)\ (p\ f)])\ \lambda f.\lambda x.f\ (x\ x)} ( λ p . ( λ q . q p ) λ p . λ f . ( p f ) ( p f ) ) λ f . λ x . f ( x x ) {\displaystyle (\lambda p.(\lambda q.q\ p)\ \lambda p.\lambda f.(p\ f)\ (p\ f))\ \lambda f.\lambda x.f\ (x\ x)}
3つ目の例として、
let x : x f = f ( x f ) in x {\displaystyle \operatorname {let} x:x\ f=f\ (x\ f)\ \operatorname {in} x} は、
( λ x . x x ) ( λ x . λ f . f ( x x f ) ) {\displaystyle (\lambda x.x\ x)\ (\lambda x.\lambda f.f\ (x\ x\ f))} ルール ラムダ式 9 let x : x f = f ( x f ) in x {\displaystyle \operatorname {let} x:x\ f=f\ (x\ f)\ \operatorname {in} x} 1 let x : x x = g e t - l a m b d a [ x , x f = f ( x f ) ] [ x := x x ] in x [ x := x x ] {\displaystyle \operatorname {let} x:x\ x=\operatorname {get-lambda} [x,x\ f=f\ (x\ f)][x:=x\ x]\ \operatorname {in} x[x:=x\ x]} 2 let x : x x = g e t - l a m b d a [ x , x = λ f . f ( x f ) ] [ x := x x ] in x x {\displaystyle \operatorname {let} x:x\ x=\operatorname {get-lambda} [x,x=\lambda f.f\ (x\ f)][x:=x\ x]\ \operatorname {in} x\ x} let x : x x = ( λ f . f ( x f ) ) [ x := x x ] in x x {\displaystyle \operatorname {let} x:x\ x=(\lambda f.f\ (x\ f))[x:=x\ x]\ \operatorname {in} x\ x} 7 let x : x x = λ f . f ( x x f ) in x x {\displaystyle \operatorname {let} x:x\ x=\lambda f.f\ (x\ x\ f)\ \operatorname {in} x\ x} 1 ( λ x . x x ) g e t - l a m b d a [ x , x x = λ f . f ( x x f ) ] {\displaystyle (\lambda x.x\ x)\ \operatorname {get-lambda} [x,x\ x=\lambda f.f\ (x\ x\ f)]} 2 ( λ x . x x ) g e t - l a m b d a [ x , x = λ x . λ f . f ( x x f ) ] {\displaystyle (\lambda x.x\ x)\ \operatorname {get-lambda} [x,x=\lambda x.\lambda f.f\ (x\ x\ f)]} ( λ x . x x ) ( λ x . λ f . f ( x x f ) ) {\displaystyle (\lambda x.x\ x)\ (\lambda x.\lambda f.f\ (x\ x\ f))}
4番目の例として、
let x : x = f x in x {\displaystyle \operatorname {let} x:x=f\ x\ \operatorname {in} x} は、
( λ x . x x ) ( λ x . f ( x x ) ) {\displaystyle (\lambda x.x\ x)\ (\lambda x.f\ (x\ x))} これは有名な y コンビネータ です。
ルール ラムダ式 9 let x : x = f x in x {\displaystyle \operatorname {let} x:x=f\ x\ \operatorname {in} x} 2 let x : x x = g e t - l a m b d a [ x , x = f x ] [ x := x x ] in x [ x := x x ] {\displaystyle \operatorname {let} x:x\ x=\operatorname {get-lambda} [x,x=f\ x][x:=x\ x]\ \operatorname {in} x[x:=x\ x]} let x : x x = ( f x ) [ x := x x ] in x x {\displaystyle \operatorname {let} x:x\ x=(f\ x)[x:=x\ x]\ \operatorname {in} x\ x} 7 let x : x x = f ( x x ) in x x {\displaystyle \operatorname {let} x:x\ x=f\ (x\ x)\ \operatorname {in} x\ x} 1 ( λ x . x x ) g e t - l a m b d a [ x , x x = f ( x x ) ] {\displaystyle (\lambda x.x\ x)\ \operatorname {get-lambda} [x,x\ x=f\ (x\ x)]} 2 ( λ x . x x ) g e t - l a m b d a [ x , x = λ x . f ( x x ) ] {\displaystyle (\lambda x.x\ x)\ \operatorname {get-lambda} [x,x=\lambda x.f\ (x\ x)]} ( λ x . x x ) ( λ x . f ( x x ) ) {\displaystyle (\lambda x.x\ x)\ (\lambda x.f\ (x\ x))}
主要人物
参照
参考文献 ^ 「PCFは、スコットの計算可能関数の論理であるLCFに基づいた、計算可能関数のためのプログラミング言語です」(Plotkin 1977)。Programming Computable Functionsは、 (Mitchell 1996)で使用されています。これは 、Programming with Computable Functions または Programming language for Computable Functions とも呼ばれます 。 ^ 「Scheme - 変数と Let 式」。 ^ Simon, Marlow (2010). 「Haskell 2010 言語レポート - Let 式」 ^ Landin, Peter J. (1964). 「式の機械的な評価」. コンピュータジャーナル . 6 (4). 英国コンピュータ協会 : 308–320 . doi : 10.1093/comjnl/6.4.308 . ^ 「相互再帰のための最も単純な多変数固定小数点コンビネータ」。
引用文献 ミッチェル、ジョン・C. (1996). 『プログラミング言語の基礎』MIT出版. ISBN 978-0-262-13321-0 。 Plotkin, GD (1977年12月). 「プログラミング言語としてのLCF」. 理論計算機科学 . 5 (3): 223– 255. doi : 10.1016/0304-3975(77)90044-5 .