23 martie 2010

Functii cu continuari in Scheme


Diverse feluri de a calcula suma elementelor unei liste

; in mod normal

(define sum_list
(lambda (l)
(letrec ((sum (lambda (l s)
(if (null? l) s
(sum (cdr l) (+ s (car l)))))))
(sum l 0))))

; cu afisare pe parcurs- propagare de la un apel la altul

(define sum_list
(lambda (l)
(letrec ((sum (lambda (l s)
(if (null? l) s
(let ((result (sum (cdr l) (+ s (car l)))))
(display result)
result))))) ; ultima expresie din secventa dicteaza valoarea la care se evalueaza let, respectiv ramura else
(sum l 0))))
(sum_list '(0 3 6))

; propagare direct catre primul apel

(define sum_list
(lambda (l)
(call/cc ; call continuation
(lambda (cont)
(letrec ((sum (lambda (l s)
(if (null? l) (cont s) ; se abandoneaza , se intoarce in call/cc si il pune pe s
; reia procesul de evaluare a apelului initial, furnizandu-i valoarea corespunzatoare
(let ((result (sum (cdr l) (+ s (car l)))))
(display result)
result)))))
(sum l 0))))))
; (sum_list '(1 2 3)) ; 6

; cu verificare ca ceea ce se aduna e numar

(define sum_list
(lambda (l)
(call/cc
(lambda (cont)
(letrec ((sum (lambda (l s)
(cond
((null? l) (cont s))
((number? (car l)) (sum (cdr l) (+ s (car l))))
(else (cont 0)))))) ; valoarea speciala 0, in caz de eroare - "aruncare de exceptii"
(sum l 0))))))
(sum_list '(1 2 3)) ; 6
(sum_list '(1 2 scheme rulz)) ; 0

; adunarea unor nr cu succ, pred, zero??
; fctii add , sub , mult , div (2 numere) folosind fct si continuari

(define succ
(lambda (x)
(+ x 1)))

(define pred
(lambda (x)
(- x 1)))

(define zero??
(lambda (x)
(if (= 0 x) #t #f)))

(define unu??
(lambda (x)
(if (= 1 x) #t #f)))

; adunare normala

(define add
(lambda (a b)
(cond
((zero?? b) a)
(else (add (succ a) (pred b))))))

; adunare cu continuari

(define add2
(lambda (a b)
(call/cc
(lambda (cont)
(letrec ((adds (lambda (a b)
(if (zero?? b) (cont a)
(let ((result (adds (succ a) (pred b) )))
(display result)
result)))))
(adds a b))))) )

; scadere normala

(define sub
(lambda(a b)
(cond
((zero?? b) a)
(else (sub (pred a) (pred b)))
)))

; scadere cu continuari

(define sub2
(lambda (a b)
(call/cc
(lambda (cont)
(letrec ((subs (lambda (a b)
(if (zero?? b) (cont a)
(let ((result (subs (pred a) (pred b))))
(display result)
result)))))
(subs a b))))))

; inmultire nr naturale

(define mult ; c contor =de la 1 ..... b se aduna a, acum = acumulator
(lambda (a b c acum)
(call/cc
(lambda (cont)
(letrec ((mul (lambda (a b c acum)
(if (= c b) (cont acum)
(let ((acum (add2 acum a)) (c (succ c)))
(mul a b c acum))))))
(mul a b c acum)
)))))

;(mult 3 8 0 0)

; impartire exacta pt nr naturale

(define div
(lambda (a b c) ; c = contor
(call/cc
(lambda (cont)
(letrec ((di (lambda (a b c)
(if (zero?? a) (cont c)
( let ((result (sub2 a b)))
(di result b (succ c)))))))
(di a b 0)
)))))

;(div 21 3 0)

Niciun comentariu: