问题
;; An ATOM is one of:
;; -- Symbol
;; -- String
;; -- Number
;; An SEXP (S-expression) is one of:
;; -- empty
;; -- (cons ATOM SEXP)
;; -- (cons SEXP SEXP)
So i'm trying to sum up all the numbers in SEXP! Here's my code,
;; sum-numbers: sexp -> Number
(define (sum-numbers sexp)
(cond
[(empty? sexp) 0]
[(ATOM? (first sexp)) (+ (atom-sum-numbers (first sexp))
(sum-numbers (rest sexp)))]
[(SEXP? (first sexp)) (+ (sum-numbers (first sexp))
(sum-numbers (rest sexp)))]))
;; atom-sum-numbers: Atom -> Number
(define (atom-sum-numbers a)
(cond
[(symbol? a) 0]
[(number? a) (+ (ATOM-number a)
(atom-sum-numbers a))]
[(string? a) 0]))
However, an error says cond
: all question results were false. I'm wondering what happened there.
回答1:
You're mixing struct accessor procedures with list manipulation procedures, that won't work - you have to be consistent, if using structs then you must use the struct's own procedures.
Also, your ATOM
structure looks wrong, as it is, it's saying: an atom is made up of a symbol, a string and a number (the three things, not just one of them!). Of course, the symbol?
, number?
and string?
predicates won't work for that struct, that's why cond
is complaining that all of the conditions are false.
I suggest you try something else, where the atoms are really atoms, not structs. Otherwise you'll have to rethink the ATOM
structure, in its current form won't work in the way you imagine. For instance, this will work:
(define (sum-numbers sexp)
(cond
[(empty? sexp) 0]
[(SEXP? (SEXP-ATOM sexp)) (+ (sum-numbers (SEXP-ATOM sexp))
(sum-numbers (SEXP-SEXP sexp)))]
[else (+ (atom-sum-numbers (SEXP-ATOM sexp))
(sum-numbers (SEXP-SEXP sexp)))]))
(define (atom-sum-numbers a)
(cond
[(symbol? a) 0]
[(number? a) a]
[(string? a) 0]))
Let's test it, and notice how atoms are plain Scheme atoms, not instances of the ATOM
struct:
(sum-numbers
(make-SEXP 'x
(make-SEXP 7
(make-SEXP "a"
'()))))
=> 7
回答2:
;; atom? : Any -> Boolean
;; true if input is an Atom false otherwise
(define (atom? at)
(or (number? at)
(symbol? at)
(string? at)))
;; sexp? : Any -> Boolean
;; true if input is n Sexp, false otherwise
(define (sexp? s)
(or
(empty? s)
(and (cons? s)
(atom? (first s))
(sexp? (rest s)))
(and (cons? s)
(sexp? (first s))
(sexp? (rest s)))))
;; sum-numbers: sexp -> Number
;; given a sexp returns the sum of all the Numbers in the list
;; sum-numbers: Sexp -> Number
(define (sum-numbers sexp)
(cond
[(empty? sexp) 0]
[(atom? (first sexp)) (+ (atom-sum-numbers (first sexp))
(sum-numbers (rest sexp)))]
[(sexp? (first sexp)) (+ (sum-numbers (first sexp))
(sum-numbers (rest sexp)))]))
;; atom-sum-numbers: anything(symbol number or string) -> Number
;; if the given is a number, add it
(define (atom-sum-numbers a)
(cond
[(symbol? a) 0]
[(number? a) a]
[(string? a) 0]))
来源:https://stackoverflow.com/questions/26747178/scheme-how-do-you-sum-numbers-in-a-list-when-you-have-structures-and-list-of-lis