(define list-sum
  (letrec
      ([helper
        (lambda (ls)
          (if (null? ls)
              0
              (+ (car ls) (helper (cdr ls)))))])
    helper))

;-------------------------------------

(define list-product
  (letrec
      ([helper
        (lambda (ls)
          (if (null? ls)
              1
              (* (car ls) (helper (cdr ls)))))])
    helper))

;-------------------------------------

(define member?             ; original definition
  (lambda (item ls)
    (if (null? ls)
        #f
        (or (eq? (car ls) item)
            (member? (cdr ls))))))


(define member?             ; curried version
    (lambda (item ls)
          ((member?-c item) ls)))


(define member?-c
  (lambda (item)
    (letrec ([helper
              (lambda (ls)
                (if (null? ls)
                    #f
                    (or (eq? (car ls) item)
                        (helper (cdr ls)))))])
      helper)))

;-------------------------------------

(define map                 ; original definition
  (lambda (proc ls)
    (if (null? ls)
        '()
        (cons (proc (car ls) (map (cdr ls)))))))

(define map                 ;curried version
    (lambda (proc ls)
          ((apply-to-all proc) ls)))


(define apply-to-all
  (lambda  (proc)
    (letrec
        ([helper
          (lambda (ls)
            (if (null? ls)
                '()
                (cons (proc (car ls))
                      (helper (cdr ls)))))])
      helper)))

;-------------------------------------

(define list-recur
  (lambda (base-value list-proc)
    (letrec
        ([helper
          (lambda (ls)
            (if (null? ls)
                base-value
                (list-proc (car ls) (helper (cdr ls)))))])
      helper)))

;-------------------------------------

(define list-sum (list-recur 0 +))

(define list-prod (list-recur 1 *))

(define member?-c
  (lambda (item)
    (list-recur #f
		(lambda (x y)
		  (or (eq? x item)
		      y)))))

(define apply-to-all
  (lambda (proc)
    (list-recur '()
		(lambda (x y)
		  (cons (proc x) y)))))

(define length (list-recur 0 (lambda (x y) (+ 1 y))))

;-------------------------------------
  
(list-sum '(2 3 4 5))

(list-prod '(2 3 4 5))

((apply-to-all add1) '(2 3 4 5))
	   
((member?-c 4) '(2 3 4 5))
((member?-c 6) '(2 3 4 5))

(length '(2 3 4 5)))