Risposte:
Prima codifica i numeri e le coppie naturali, come descritto da jmad.
Rappresenta un numero intero come coppia di numeri naturali tale che . Quindi puoi definire le normali operazioni sugli interi come (usando la notazione di Haskell per -calculus):λ
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)
Il caso dei numeri complessi è simile nel senso che un numero complesso è codificato come una coppia di reali. Ma una domanda più complicata è come codificare i reali. Qui devi fare più lavoro:
La codifica di reals richiede molto lavoro e non si desidera farlo effettivamente nel calcolo . Ma vedi ad esempio la sottodirectory di Marshall per una semplice implementazione dei reali in puro Haskell. In linea di principio, ciò potrebbe essere tradotto nel puro calcolo λ .etc/haskell
i:ℤ
, x:a
, f,u,s:a→a
, p:(a→a,a→a)
] Se si codificano ℤ come (Sign,ℕ)
allora, data una coppia di funzioni (s,f)
come p
, il termine λi.λp.λx.(fst i) (fst p) id ((snd i) (snd p) x)
produrrà sia f(…f(x)…)
o s(f(…f(x)…))
(se il risultato è negativo). Se codifichi ℤ come (ℕ,ℕ)
, hai bisogno di una funzione che ha un'inverso - data una coppia (f,u)
e x
, la funzione λi.λp.λx.(snd i)(snd p)((fst i)(fst p) x)
produrrà a u(…u(f(…f(x)…))…)
cui lasceranno i tempi f
applicati . Entrambi funzionano in contesti diversi (il risultato può essere "capovolto" || è invertibile). i
x
f
fold . ctor
per qualsiasi costruttore e quel tipo fold
( r
). (Ecco perché, per i tipi ricorsivi, i dati "ricorrono da soli". Per i tipi non ricorsivi è più simile a una case
corrispondenza / pattern.)
Il lambda-calcolo può codificare la maggior parte delle strutture di dati e dei tipi di base. Ad esempio, puoi codificare una coppia di termini esistenti nel calcolo lambda, usando la stessa codifica Church che di solito vedi per codificare interi non negativi e booleano:
fst = λ p . p ( λ x y . x ) snd = λ p . p ( λ x y . y )
Poi la coppia è p = ( accoppiare un b ) e se si vuole tornare a e b si può fare ( FST p ) e ( snd p ) .
Ciò significa che puoi rappresentare facilmente numeri interi positivi e negativi con una coppia: il segno a sinistra e il valore assoluto a destra. Il segno è un valore booleano che specifica se il numero è positivo. Il diritto è un numero naturale che usa la codifica della Chiesa.
E ora che hai numeri interi relativi. La moltiplicazione è facile da definire, devi solo applicare la funzione sul segno e la moltiplicazione su numeri naturali sul valore assoluto:
Per definire l'aggiunta, devi confrontare due numeri naturali e usare la sottrazione quando i segni sono diversi, quindi questo non è un termine λ ma puoi adattarlo se vuoi davvero:
ma poi la sottrazione è davvero facile da definire: