Domanda

I know you can write a simple factorial function by doing this:

(define fact
  (lambda (n)
    (if (= n 0) 1
        (* n (fact (- n 1)))))

However, that will only work if you send in a number; it will error if you send in a list or symbol. So what I want to do is make it work for everything and, if a list, do the factorial of each individual element in the list. Here is what I have:

(define listFact
 (lambda (n)
   (cond
     ((null? n) 1)
     ((symbol? n) n)
     ((number? n) (if (= n 0) 1 (* n (listFact (- n 1)))))
     ((cons? n) (cons (listFact(car n)) (listFact(cdr n)))))))

I'm not too great at Scheme, but I need to be able to know the basics. Every input works properly except for a list.

> (listFact '())

1

(listFact 'a)

'a

(listFact 4)

24

(listFact '(1 2 3))

cons: second argument must be a list, but received 6 and 1

What I want that last one to do is return:

(list 1 2 6)

I have no idea why it won't work. If anyone could help me figure this one out without changing the entire structure of the code (i.e. don't use apply/map or multiple functions), it would be much appreciated. I'd assume the only line messed up is the one with cons.

Thanks.

È stato utile?

Soluzione

Just replace

(cond
     ((null? n) 1)

with

(cond
     ((null? n) n)

for cons to work properly, because of the trailing nil: a list (1 2 3) is actually (1 . (2 . (3 . ()))), so you eventually get to the sentinel nil in the end of the list. To reconstruct the list back, you need it to remain an empty list, or nil, so that (cons 6 nil) creates a new list (6); (cons 6 1) would create a pair (6 . 1) but apparently it doesn't work in your implementation for some reason.

If you want your () elements in a list to be transformed into 1s, you will have to distinguish the two cases.

Altri suggerimenti

Here's your problem :

((null? n) 1)

So, when you try to get the value of an empty list, you get an integer, which is not a list. When your call your function with a list, you get something like that :

(cons 1 (cons 2 (cons 6 1)))

This doesn't work. In order to fix your function, you should try this :

((null? n) n)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top