scheme how do you sum numbers in a list when you have structures and list of lists

流过昼夜 提交于 2019-12-12 04:34:10

问题


;; 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!