简体   繁体   中英

Recursive Function Scheme Programming

How do I make a recursive function from my current code? I'm still new to scheme so I don't really understand the basic tbh.

so for now I am only able to run the function (total_func "SST" 2) and I want to make it (total_func '(("SST" 2) ("LST" 1) ("JNS" 3)) )

this is my current code.

(define (total_func code quan);total_func is the function name
  (if (equal? code "SST")
    (define price 20))

  (if (equal? code "LST")
    (define price 25))

  (if (equal? code "JNS")
    (define price 70))
  
(define total (* price quan));total will calculate price * quantity
(print total);display the total value```

First of all, let's break things down a bit.

We have some sort of product code with a fixed price. Let's handle that in a function

(define (code->price code)
  (cond
    ((equal? code "SST") 20)
    ((equal? code "LST") 25)
    ((equal? code "JNS") 70)
    (else 999)))

You can now test this code by just calling (code->price "SST") .

Note that there is an else at the end - you didn't say what to do when the code isn't recognized.

Now, you seem to have a list of "orders" which comprise a (CODE QUANTITY) pairing. Note that a "pair" in scheme is a particular thing that is slightly different from a list of two items. What you have shown is a list of two items, so I'll use that.

; order = (code quantity) - a list of 2 items
(define (order->price order)
  (let ((code (car order))
        (quan (cadr order)))
    (* quan (code->price code))))

And if we test this with (order->price '("SST" 2)) we get 40 which is reassuring. Now, we clearly just need a way to run that for each of the orders in our order-list and add up the results.

(define (recursive-totaller subtot orders)
  (if (null? orders)
    subtot
    (let ((new-subtot (+ subtot (order->price (car orders)))))
      (recursive-totaller new-subtot (cdr orders)))))

Now, a recursive function is going to need the same "shape" for its parameters in every call, from the first to the last. So we are going to give it a subtot that for the first call will be 0. If our list of orders is empty then we will just return whatever the current subtot will be - which for an empty list is 0, which is correct.

If orders is not empty, we calculate a new sub-total by calling order->price on the first item in orders . Then we recurse, calling ourself with the new subtotal and the tail of the orders list.

Assuming our list of orders is not infinite we will eventually call ourselves with an empty list and just return the final sub-total all the way back through the call-stack until it reaches the original caller.

(define (test-totaller)
  (recursive-totaller 0 '(("SST" 2) ("LST" 1) ("JNS" 3))))

Now, you might not be quite so verbose in "real" code, but to be honest I'd rather several functions like this that are clear about what they do rather than one bigger function that is harder to understand.

Finally - applying the same function to all the elements of a list and getting a new list back is very common (it is called "mapping") and summarizing a list is also very common (it is called "folding") and scheme has functions to help you (you may need to import "srfi-1").

(let* ((orders '(("SST" 2) ("LST" 1) ("JNS" 3)))
       (order-prices (map order->price orders)))
  (fold + 0 order-prices)))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM