回答:
jmadの説明に従って、最初に自然数とペアをエンコードします。
整数を、ような自然数ペアとして表します。次に、整数の通常の操作を次のように定義できます( -calculusのHaskell表記を使用):(、B )K = - bはλ
neg = \k -> (snd k, fst k)
add = \k m -> (fst k + fst m, snd k + snd m)
sub = \k m -> add k (neg m)
mul = \k m -> (fst k * fst m + snd k * snd m, fst k * snd m + snd k * fst m)
複素数の場合は、複素数が実数のペアとしてエンコードされるという意味で似ています。しかし、より複雑な問題は、実数をエンコードする方法です。ここでは、さらに作業を行う必要があります。
実数のエンコードは大変な作業であり、 -calculus で実際に行うのは望ましくありません。しかし、純粋なHaskellでの実数の簡単な実装については、例えばMarshallのサブディレクトリを参照してください。これは原則として、純粋な -calculusに変換できます。etc/haskell
i:ℤ
、x:a
、f,u,s:a→a
、p:(a→a,a→a)
]は、としてℤを符号化した場合(Sign,ℕ)
、その後、機能の一対所与(s,f)
としてp
、この用語は、λi.λp.λx.(fst i) (fst p) id ((snd i) (snd p) x)
いずれか生成するf(…f(x)…)
か、s(f(…f(x)…))
(結果が負の場合)。あなたのようにℤをエンコードした場合(ℕ,ℕ)
、あなたは逆を持っている機能を必要とする-ペア与えられた(f,u)
とx
、関数がλi.λp.λx.(snd i)(snd p)((fst i)(fst p) x)
生成されますu(…u(f(…f(x)…))…)
残しているf
応用i
に回x
。両方とも異なるコンテキストで動作します(結果は「反転」できます|| f
は可逆です)。
fold . ctor
任意のコンストラクタのために、そのタイプのfold
(r
)。(これが、再帰型の場合、データが「それ自体で再帰する」理由です。非再帰型の場合は、case
/パターンマッチに似ています。)
ラムダ計算は、ほとんどのデータ構造と基本型をエンコードできます。たとえば、非負の整数とブール値をエンコードするために通常表示されるのと同じ教会エンコードを使用して、ラムダ計算の既存の用語のペアをエンコードできます。
、FST = λ P 。P (λ X 、Y 。X )SND = λ P 。P (λ X 、Y 。Y )
次にペアあるとあなたが戻って取得したい場合やあなたが行うことができますと 。p = (ペア a b )a b (fst p )(snd p )
これは、正と負の整数をペアで簡単に表すことができることを意味します:左側の符号と右側の絶対値。符号は、数値が正かどうかを指定するブール値です。権利は、教会のエンコードを使用した自然数です。
そして今、あなたは相対的な整数を持っている。乗算の定義は簡単です。符号に関数を適用し、絶対値に自然数の乗算を適用するだけです。
加算を定義するには、2つの自然数を比較し、符号が異なるときに減算を使用する必要があるため、これはλ項ではありませんが、本当に必要な場合は調整できます。
しかし、減算は本当に簡単に定義できます:
正と負の整数が得られたら、複雑な整数を非常に簡単に定義できますを表すの 2つの整数ペアです。その後、加算はポイント単位で、乗算は通常どおりですが、私はそれを書かないでしょう、それは簡単なはずです: