Created
January 21, 2016 11:26
-
-
Save FedericoPonzi/d0f192079ab633be866c to your computer and use it in GitHub Desktop.
Church numbers in sml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* numeri di Church *) | |
val zero = fn f => fn x => x; | |
val uno = fn f => fn x => f x; | |
val due = fn f => fn x => f (f x); | |
val tre = fn f => fn x => f (f (f x)); | |
(* dato un naturale, si ottiene il corrispondente numero | |
di Church applicando la seguente funzione di codifica *) | |
fun codifica 0 = (fn y => (fn x => x)) | |
| codifica n = (fn y => (fn x => (y (codifica (n-1) y x)))); | |
(* la decodifica (dato un Church restituisce il naturale) e`: *) | |
fun eval f = f (fn x => x+1) 0; | |
eval (codifica 5); | |
(* successore *) | |
fun succ z = (fn x => fn y => x (z x y)); | |
(* somma *) | |
fun somma n m f x = (n f (m f x)); | |
(* predecessore alla Kleene, cioe` usando le coppie *) | |
fun Kpred z = (let val doublesucc = (fn (u,v) => (succ u, u)) in | |
(let val (x,y) = (z doublesucc (zero, zero)) in y end) end); | |
(* predecessore senza coppie *) | |
fun pred z x y = z (fn g => fn h => h (g x)) (fn w => y) (fn w => w); | |
(* sottrazione *) | |
fun minus x y = y pred x; | |
eval (minus due uno); | |
(* ma... | |
eval (minus due due); | |
produce errore!!! *) | |
(* moltiplicazione *) | |
fun times1 m n = m (somma n) zero; (* oppure *) | |
fun times2 m n f = m (n f); | |
(* fattoriale - stessa idea del predecessore di Kleene *) | |
fun fact n = let val step = (fn (x,y) => (succ x, times2 (succ x) y)) in | |
(let val (a,b) = (n step (zero, uno)) in b end) end; | |
(* elevamento a potenza *) | |
fun power1 m n = n (times1 m) uno; (* oppure *) | |
fun power2 m n f = n m f; | |
eval (times1 tre due); | |
eval (times2 tre due); | |
eval (power1 tre due); | |
eval (power2 tre due); | |
(* auto-elevamento a potenza *) | |
fun selfpow1 n = power1 n n; | |
eval (selfpow1 tre); | |
(* auto-elevamento a potenza usando power2: | |
fun selfpow2 n = power2 n n; | |
ATTENZIONE: questa definizione produce errore: | |
Error: operator and operand don't agree [circularity] | |
operator domain: 'Z -> 'Y -> 'X | |
operand: 'Z | |
in expression: | |
(power2 n) n | |
*) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment