답변:
먼저 jmad가 설명한대로 자연수와 쌍을 인코딩하십시오.
정수 표현 자연수의 쌍 ( , B ) 이되도록 K = - B를 . 그런 다음 정수에 대한 일반적인 연산을 다음과 같이 정의 할 수 있습니다 ( λ -calculus에 Haskell 표기법 사용 ).
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)
복소수의 경우는 복소수가 한 쌍의 실수로 인코딩된다는 점에서 비슷합니다. 그러나 더 복잡한 질문은 실수를 인코딩하는 방법입니다. 여기서 더 많은 일을해야합니다.
실수를 인코딩하는 것은 많은 작업이며 실제로 미적분학 에서는 원하지 않습니다 . 그러나 순수한 Haskell에서 실수를 간단히 구현하려면 Marshall 의 하위 디렉토리를 참조하십시오 . 이것은 원칙적으로 순수한 λ- 미적분 으로 변환 될 수 있습니다 .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 = ( pair a b ) 이며 a 와 b 를 되 찾으려면 ( fst p ) 및 ( snd p )를 수행 할 수 있습니다 .
즉, 왼쪽의 부호와 오른쪽의 절대 값 쌍으로 양수와 음수를 쉽게 표현할 수 있습니다. 부호는 숫자가 양수인지 여부를 지정하는 부울입니다. 오른쪽은 교회 인코딩을 사용하는 자연수입니다.
이제 상대 정수가 생겼습니다. 곱셈을 쉽게 정의 할 수 있습니다. xor 만 적용하면됩니다. 함수 를 부호에 자연수에 대한 곱셈을 절대 값에 적용하면됩니다.
더하기를 정의하려면 두 개의 자연수를 비교하고 부호가 다를 때 빼기를 사용해야하므로 이것은 λ 항이 아니지만 실제로 원하는 경우이를 조정할 수 있습니다.
그러나 빼기는 정의하기가 정말 쉽습니다.
양의 정수와 음의 정수가 있으면 복잡한 정수를 매우 쉽게 정의 할 수 있습니다. 두 정수의 쌍일뿐입니다. 어느 것을 나타내는 . 그런 다음 덧셈은 포인트 방식이며 곱셈은 평소 와 같지만 쓰지 않을 것입니다.